所以我写的脚本有一个小问题。我有一个看起来像这样的文本文件:
'20 zebra 12 bear'
这只是一个例子,格式是1行,所有项目用空格分隔。该脚本可以对它们进行排序,并对字符串执行其他一些操作,但我无法弄清楚的是如何保持它的设置方式。例如,上面的行应该像这样排序:
12
bear
20
zebra
我需要在数字位置保留一个数字并在字符串中保留一个字符串,但它们应按字母顺序排序。 到目前为止,这是我的脚本:
#!/usr/bin/python
# Make sure you use the proper modules.
import sys, string
# This area defines the arguments and returns a usage message should it be used incorrectly.
try:
infilename = sys.argv[1]; outfilename = sys.argv[2]
except:
print "Usage:",sys.argv[0], "infile outfile"; sys.exit(1)
ifile = open(infilename, 'r') # Opens the input file for reading
ofile = open(outfilename, 'w') # Opens the output file for writing
data = ifile.readlines()[0].split() # Reads the lines on the input file
# The items in the list are sorted here and defined by a space.
sort = sorted(data, key=lambda item: (int(item.partition(' ')[0])
if item[0].isdigit() else float('inf'), item))
# Use this to remove any special characters in the list
filtered = [s.translate(None, string.punctuation) for s in sort]
ofile.write('\n'.join(filtered)) # Writes the final output to file (one on each line)
ifile.close() # Closes the input file
ofile.close() # Closes the output file
我知道这不是最漂亮但我没有长时间使用Python,所以如果你有关于如何使它更漂亮的建议,我会全神贯注。我真正需要的是将数字和字符串保持为字符串,但交换它们以进行排序。感谢您给予的任何帮助。
答案 0 :(得分:2)
这是一个非常奇怪的问题。
def strange_sort(seq):
"""
Sorts digitstrings (by integer value) and non-digitstrings in a
sequence among themselves, preserving the original ds/non-ds
signature.
"""
numbers = iter(sorted((elem for elem in seq if elem.isdigit()), key=int))
words = iter(sorted(elem for elem in seq if not elem.isdigit()))
final = [next(numbers if elem.isdigit() else words) for elem in seq]
return final
给出了
>>> strange_sort("1 2 3".split())
['1', '2', '3']
>>> strange_sort("1 2 10 3".split())
['1', '2', '3', '10']
>>> strange_sort("1 2 10 3 bear".split())
['1', '2', '3', '10', 'bear']
>>> strange_sort("2 1 bear 10 3".split())
['1', '2', 'bear', '3', '10']
>>> strange_sort("2 1 zebra 10 3 bear".split())
['1', '2', 'bear', '3', '10', 'zebra']
>>> strange_sort("20 zebra 12 bear".split())
['12', 'bear', '20', 'zebra']
>>> strange_sort("20 zebra 12 bear 3".split())
['3', 'bear', '12', 'zebra', '20']
实际上,这基本上是@ przemo_li的建议。
[编辑以保持所有字符串]
答案 1 :(得分:1)
您需要做的是创建第3个列表。数字为1,字符串为2。
所以你的例子就是
1,2,1,2。
比将所有数字放在一个列表中,而将字符串放在第二个列表中。对它们进行排序。
比用第3个字符串中的每个1替换下一个数字,每个2用下一个字符串替换。
它应该完美无缺。
答案 2 :(得分:1)
对于交错数字和字符串的特定情况,请使用列表切片:
text = '20 zebra 12 bear 5 moose'
arr = text.split()
arr[::2] = sorted(arr[::2], key=int)
arr[1::2] = sorted(arr[1::2])
print ' '.join(arr)
输出:
5 bear 12 moose 20 zebra
对于一般情况,内容可能没有完全交错(例如'20 15斑马12 17牛熊'),你可以使用Numpy:
import numpy as np
text = '20 15 zebra 12 17 cow bear 5 2 1'
arr = np.char.array(text.split())
nums = arr.isdigit()
strs = ~nums
arr[nums] = sorted(arr[nums], key=int)
arr[strs] = np.sort(arr[strs])
print ' '.join(arr)
输出:
1 2 bear 5 12 cow zebra 15 17 20
答案 3 :(得分:0)
我会这样做:
re.split
。如果你需要它回到字符串:
这是执行此操作的代码:
#!/usr/bin/python
import re
data = "12 foo 35 bar 10 baz 23 foobar"
d = re.split("\s+", data)
tuples = zip(d[0::2], d[1::2])
tuples.sort()
# If you need it back to a string
dsorted = [x + " " + y for (x, y) in tuples]
datasorted = " ".join(dsorted)
print data
print datasorted
这输出以下内容:
12 foo 35 bar 10 baz 23 foobar
10 baz 12 foo 23 foobar 35 bar