我有以下数据结构(列表清单)
[
['4', '21', '1', '14', '2008-10-24 15:42:58'],
['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
['5', '21', '3', '19', '2008-10-24 15:45:45'],
['6', '21', '1', '1somename', '2008-10-24 15:45:49'],
['7', '22', '3', '2somename', '2008-10-24 15:45:51']
]
我希望能够
使用函数对列表重新排序,以便我可以按列表中的每个项目进行分组。例如,我希望能够按第二列分组(以便所有21个都在一起)
使用函数仅显示每个内部列表中的某些值。例如,我想将此列表缩小为仅包含'2somename'的第4个字段值
所以列表看起来像这样
[
['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
['7', '22', '3', '2somename', '2008-10-24 15:45:51']
]
答案 0 :(得分:57)
对于第一个问题,您应该做的第一件事是使用运算符模块中的itemgetter按第二个字段对列表进行排序:
x = [
['4', '21', '1', '14', '2008-10-24 15:42:58'],
['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
['5', '21', '3', '19', '2008-10-24 15:45:45'],
['6', '21', '1', '1somename', '2008-10-24 15:45:49'],
['7', '22', '3', '2somename', '2008-10-24 15:45:51']
]
from operator import itemgetter
x.sort(key=itemgetter(1))
然后你可以使用itertools'groupby函数:
from itertools import groupby
y = groupby(x, itemgetter(1))
现在y是一个包含(element,item iterator)元组的迭代器。解释这些元组比显示代码更令人困惑:
for elt, items in groupby(x, itemgetter(1)):
print(elt, items)
for i in items:
print(i)
打印哪些:
21 <itertools._grouper object at 0x511a0>
['4', '21', '1', '14', '2008-10-24 15:42:58']
['5', '21', '3', '19', '2008-10-24 15:45:45']
['6', '21', '1', '1somename', '2008-10-24 15:45:49']
22 <itertools._grouper object at 0x51170>
['3', '22', '4', '2somename', '2008-10-24 15:22:03']
['7', '22', '3', '2somename', '2008-10-24 15:45:51']
对于第二部分,您应该使用已在此处提到的列表推导:
from pprint import pprint as pp
pp([y for y in x if y[3] == '2somename'])
打印哪些:
[['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
['7', '22', '3', '2somename', '2008-10-24 15:45:51']]
答案 1 :(得分:11)
如果您将其分配给var“a”......
python 2.x:
#1:
a.sort(lambda x,y: cmp(x[1], y[1]))
#2:
filter(lambda x: x[3]=="2somename", a)
python 3:
#1:
a.sort(key=lambda x: x[1])
答案 2 :(得分:3)
如果我正确理解您的问题,以下代码应该完成这项工作:
l = [
['4', '21', '1', '14', '2008-10-24 15:42:58'],
['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
['5', '21', '3', '19', '2008-10-24 15:45:45'],
['6', '21', '1', '1somename', '2008-10-24 15:45:49'],
['7', '22', '3', '2somename', '2008-10-24 15:45:51']
]
def compareField(field):
def c(l1,l2):
return cmp(l1[field], l2[field])
return c
# Use compareField(1) as the ordering criterion, i.e. sort only with
# respect to the 2nd field
l.sort(compareField(1))
for row in l: print row
print
# Select only those sublists for which 4th field=='2somename'
l2somename = [row for row in l if row[3]=='2somename']
for row in l2somename: print row
输出:
['4', '21', '1', '14', '2008-10-24 15:42:58']
['5', '21', '3', '19', '2008-10-24 15:45:45']
['6', '21', '1', '1somename', '2008-10-24 15:45:49']
['3', '22', '4', '2somename', '2008-10-24 15:22:03']
['7', '22', '3', '2somename', '2008-10-24 15:45:51']
['3', '22', '4', '2somename', '2008-10-24 15:22:03']
['7', '22', '3', '2somename', '2008-10-24 15:45:51']
答案 3 :(得分:2)
使用函数对列表重新排序,以便我可以按列表中的每个项目进行分组。例如,我希望能够按第二列分组(这样所有21个都在一起)
列表具有内置的排序方法,您可以提供一个提取排序键的函数。
>>> import pprint
>>> l.sort(key = lambda ll: ll[1])
>>> pprint.pprint(l)
[['4', '21', '1', '14', '2008-10-24 15:42:58'],
['5', '21', '3', '19', '2008-10-24 15:45:45'],
['6', '21', '1', '1somename', '2008-10-24 15:45:49'],
['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
['7', '22', '3', '2somename', '2008-10-24 15:45:51']]
使用函数仅显示每个内部列表中的某些值。例如,我想将此列表缩小为仅包含'2somename'的第4个字段值
这看起来像是list comprehensions
的工作>>> [ll[3] for ll in l]
['14', '2somename', '19', '1somename', '2somename']
答案 4 :(得分:2)
如果您要进行大量的排序和过滤,您可能会喜欢一些辅助函数。
m = [
['4', '21', '1', '14', '2008-10-24 15:42:58'],
['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
['5', '21', '3', '19', '2008-10-24 15:45:45'],
['6', '21', '1', '1somename', '2008-10-24 15:45:49'],
['7', '22', '3', '2somename', '2008-10-24 15:45:51']
]
# Sort and filter helpers.
sort_on = lambda pos: lambda x: x[pos]
filter_on = lambda pos,val: lambda l: l[pos] == val
# Sort by second column
m = sorted(m, key=sort_on(1))
# Filter on 4th column, where value = '2somename'
m = filter(filter_on(3,'2somename'),m)
答案 5 :(得分:2)
对于第(2)部分,x是你的数组,我想你想要,
[y for y in x if y[3] == '2somename']
这将返回一个仅包含第四个值为'2somename'的数据列表的列表...虽然看起来Kamil正在为您提供最佳的SQL建议...
答案 6 :(得分:1)
看起来很像你正试图将列表用作数据库。
现在Python在核心发行版中包含了sqlite绑定。如果您不需要持久性,那么创建内存中的sqlite数据库非常容易(参见How do I create a sqllite3 in-memory database?)。
然后,您可以使用SQL语句执行所有这些排序和过滤,而无需重新发明轮子。
答案 7 :(得分:1)
你只是在你的结构上创建索引,对吗?
>>> from collections import defaultdict
>>> def indexOn( things, pos ):
... inx= defaultdict(list)
... for t in things:
... inx[t[pos]].append(t)
... return inx
...
>>> a=[
... ['4', '21', '1', '14', '2008-10-24 15:42:58'],
... ['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
... ['5', '21', '3', '19', '2008-10-24 15:45:45'],
... ['6', '21', '1', '1somename', '2008-10-24 15:45:49'],
... ['7', '22', '3', '2somename', '2008-10-24 15:45:51']
... ]
这是您的第一个请求,按位置1分组。
>>> import pprint
>>> pprint.pprint( dict(indexOn(a,1)) )
{'21': [['4', '21', '1', '14', '2008-10-24 15:42:58'],
['5', '21', '3', '19', '2008-10-24 15:45:45'],
['6', '21', '1', '1somename', '2008-10-24 15:45:49']],
'22': [['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
['7', '22', '3', '2somename', '2008-10-24 15:45:51']]}
这是您的第二个请求,按位置3分组。
>>> dict(indexOn(a,3))
{'19': [['5', '21', '3', '19', '2008-10-24 15:45:45']], '14': [['4', '21', '1', '14', '2008-10-24 15:42:58']], '2somename': [['3', '22', '4', '2somename', '2008-10-24 15:22:03'], ['7', '22', '3', '2somename', '2008-10-24 15:45:51']], '1somename': [['6', '21', '1', '1somename', '2008-10-24 15:45:49']]}
>>> pprint.pprint(_)
{'14': [['4', '21', '1', '14', '2008-10-24 15:42:58']],
'19': [['5', '21', '3', '19', '2008-10-24 15:45:45']],
'1somename': [['6', '21', '1', '1somename', '2008-10-24 15:45:49']],
'2somename': [['3', '22', '4', '2somename', '2008-10-24 15:22:03'],
['7', '22', '3', '2somename', '2008-10-24 15:45:51']]}