我有一个如下所示的外部.txt文件:
Year of birth (yyyy); id; First name; Second name;
...
Year of birth (yyyy); id; First name; Second name;
我可以创建一个按bbbb
部分对所有元素进行排序的新列表吗?
我尝试通过拆分所有元素然后对其进行排序来做到这一点,但与此同时,我丢失了与此id
相关的其他元素。
答案 0 :(得分:1)
有很多方法可以使用内置函数和模块,或其他答案中提到的第三方库,例如pandas
。
使用简单的内置函数,可以通过将文件对象传递给sorted
函数来从文件创建排序列表:
with open(filename) as file_object:
lines = sorted(file_object)
之所以可行,是因为sorted
接受任何序列或可迭代对象。文件对象是可迭代的,并且一次产生一行。
这将从每行的第一个字符开始按字母顺序排序,然后比较第二个,依此类推。
由于要按分号之间的第二个字符串排序,因此需要提取该字符串,然后按该字符串排序。有很多方法可以做到这一点。
sorted
函数接受一个key
参数。您应该在此处传递一个函数,该函数将为每行调用,并返回将该行与其他行进行比较的条件。
例如,我们可以将行拆分为单独的字符串列表:
>>> line = '1998;1234;Jim;Smith;'
>>> line.split(';')
['1998', '1234', 'Jim', 'Smith']
然后,我们要比较列表中的第二个值(我们从0
开始计数,因此第二个值是[1]
):
>>> line.split(';')[1]
'1234'
创建一个执行此操作的函数,然后我们可以将其作为sorted
传递给key
:
def get_id(line):
return line.split(';')[1]
with open(filename) as file_object:
lines = sorted(file_object, key=get_id)
可能您希望对lines
进行更多处理,以便对于每一行都有一个值列表。 Python具有内置的csv
模块,用于处理定界值(您正在使用分号):
import csv
from operator import itemgetter
with open(filename) as file_object:
reader = csv.reader(file_object, delimiter=';')
rows = sorted(reader, key=itemgetter(1))
在这种情况下,我们可以使用itemgetter
而不用写get_id
,因为csv
模块已经为我们完成了所有拆分,我们只需要一个可以获取该行的第二项。
答案 1 :(得分:-1)
这是一个可能的答案。
文本文件中的示例项目字符串:
sample = """1998; 1; Jim; Smith;
2001; 2; Andrea; Johnson;
1995; 3; Tom; Jones;"""
我们将通过拆分字符串,拆分行并附加到主数组来创建多维数组(列表列表)。
matrix = list()
for record in sample.split('\n'):
line = [i.strip() for i in record.split(';') if len(i) > 0]
matrix .append(line)
我们的矩阵:
[
['1998', '1', 'Jim', 'Smith'],
['2001', '2', 'Andrea', 'Johnson'],
['1995', '3', 'Tom', 'Jones']
]
要排序,您可以使用列表的内置方法并实现lambda函数以选择要作为排序依据的列。注意:由于Python中的索引从零开始,因此您必须考虑到这一点。例如,x [1]表示第二项或id
列:
排序1 :降序ID顺序
matrix.sort(key=lambda x: x[1], reverse=True)
输出1:
[
['1995', '3', 'Tom', 'Jones'],
['2001', '2', 'Andrea', 'Johnson'],
['1998', '1', 'Jim', 'Smith']
]
排序2 :降序排列的出生年份顺序(从最小到最大)
matrix.sort(key=lambda x: x[0], reverse=False)
输出2:
[
['2001', '2', 'Andrea', 'Johnson'],
['1998', '1', 'Jim', 'Smith'],
['1995', '3', 'Tom', 'Jones']
]
答案 2 :(得分:-2)
list1 = """1999;id2;mike;smith;1996;id3;steve;jones;1998;id1;john;smith"""
list2 = list1.split(';')
import pandas as pd
import numpy as np
columns = ['year','id','first','last']
df = pd.DataFrame(np.reshape(list2,(-1,4)),columns=columns)
###### by='id' if you want to sort by id, or replace with('year','id','first','last') whatever you want to sort by.
df.sort_values(by='id',inplace=True)
list3 = df.values.tolist()
list3
output:
[['1998', 'id1', 'john', 'smith'],
['1999', 'id2', 'mike', 'smith'],
['1996', 'id3', 'steve', 'jones']]