我有两个列表如下:
list_1
['A-1','A-1','A-1','A-2','A-2','A-3']
list_2
['iPad','iPod','iPhone','Windows','X-box','Kindle']
我想根据list_2
中的索引值拆分list_1
。例如,
list_a1
['iPad','iPod','iPhone']
list_a2
['Windows','X-box']
list_a3
['Kindle']
我知道索引方法,但它需要匹配的值才能传递。在这种情况下,我想动态地找到list_1中具有相同值的值的索引。这可能吗?任何提示/提示都将深受赞赏。
感谢。
答案 0 :(得分:4)
有几种方法可以做到这一点。
我可以使用zip
和groupby
来完成。
首先:
>>> list(zip(list_1, list_2))
[('A-1', 'iPad'),
('A-1', 'iPod'),
('A-1', 'iPhone'),
('A-2', 'Windows'),
('A-2', 'X-box'),
('A-3', 'Kindle')]
现在:
>>> import itertools, operator
>>> [(key, list(group)) for key, group in
... itertools.groupby(zip(list_1, list_2), operator.itemgetter(0))]
[('A-1', [('A-1', 'iPad'), ('A-1', 'iPod'), ('A-1', 'iPhone')]),
('A-2', [('A-2', 'Windows'), ('A-2', 'X-box')]),
('A-3', [('A-3', 'Kindle')])]
所以,你只需要每个group
,忽略key
,你只需要group
中每个元素的第二个元素。你可以通过另一种理解来获得每个组的第二个元素,或者只是解压缩:
>>> [list(zip(*group))[1] for key, group in
... itertools.groupby(zip(list_1, list_2), operator.itemgetter(0))]
[('iPad', 'iPod', 'iPhone'), ('Windows', 'X-box'), ('Kindle',)]
我个人觉得这个单独的迭代器转换序列比一个长表达式更具可读性。采取极端:
>>> ziplists = zip(list_1, list_2)
>>> pairs = itertools.groupby(ziplists, operator.itemgetter(0))
>>> groups = (group for key, group in pairs)
>>> values = (zip(*group)[1] for group in groups)
>>> [list(value) for value in values]
...但是一个可能2或3行的快乐媒介通常比任何一种都要好。
答案 1 :(得分:2)
使用itertools.izip_longest
和itertools.groupby
:
>>> from itertools import groupby, izip_longest
>>> inds = [next(g)[0] for k, g in groupby(enumerate(list_1), key=lambda x:x[1])]
list_1
的第一组项目,并找到每个组的起始索引:
>>> inds
[0, 3, 5]
现在使用切片和izip_longest
因为我们需要成对list_2[0:3]
,list_2[3:5]
,list_2[5:]
:
>>> [list_2[x:y] for x, y in izip_longest(inds, inds[1:])]
[['iPad', 'iPod', 'iPhone'], ['Windows', 'X-box'], ['Kindle']]
要获得一系列词汇,您可以这样:
>>> inds = [next(g) for k, g in groupby(enumerate(list_1), key=lambda x:x[1])]
>>> {k: list_2[ind1: ind2[0]] for (ind1, k), ind2 in
zip_longest(inds, inds[1:], fillvalue=[None])}
{'A-1': ['iPad', 'iPod', 'iPhone'], 'A-3': ['Kindle'], 'A-2': ['Windows', 'X-box']}
答案 2 :(得分:2)
通常我是急于groupby
解决方案的人; ^)但在这里我将采用另一种方式并手动插入OrderedDict
:
list_1 = ['A-1','A-1','A-1','A-2','A-2','A-3']
list_2 = ['iPad','iPod','iPhone','Windows','X-box','Kindle']
from collections import OrderedDict
d = OrderedDict()
for code, product in zip(list_1, list_2):
d.setdefault(code, []).append(product)
生成d
看起来像
>>> d
OrderedDict([('A-1', ['iPad', 'iPod', 'iPhone']),
('A-2', ['Windows', 'X-box']), ('A-3', ['Kindle'])])
轻松访问:
>>> d["A-2"]
['Windows', 'X-box']
我们可以使用list_1
以.values()
顺序获取列表列表:
>>> d.values()
[['iPad', 'iPod', 'iPhone'], ['Windows', 'X-box'], ['Kindle']]
如果你注意到没有人告诉你如何制作一堆名为list_a1
之类的独立名单等等 - 这是因为这是一个坏主意。您希望将数据保存在一起,您可以(至少)轻松地迭代,并且字典和列表列表都符合条件。
答案 3 :(得分:2)
也许是这样的?
#!/usr/local/cpython-3.3/bin/python
import pprint
import collections
def main():
list_1 = ['A-1','A-1','A-1','A-2','A-2','A-3']
list_2 = ['iPad','iPod','iPhone','Windows','X-box','Kindle']
result = collections.defaultdict(list)
for list_1_element, list_2_element in zip(list_1, list_2):
result[list_1_element].append(list_2_element)
pprint.pprint(result)
main()
答案 4 :(得分:0)
你可以这样做,如果你想要简单的代码,它不是很漂亮,但可以完成工作。
list_1 = ['A-1','A-1','A-1','A-2','A-2','A-3']
list_2 = ['iPad','iPod','iPhone','Windows','X-box','Kindle']
list_1a = []
list_1b = []
list_1c = []
place = 0
for i in list_1[::1]:
if list_1[place] == 'A-1':
list_1a.append(list_2[place])
elif list_1[place] == 'A-2':
list_1b.append(list_2[place])
else:
list_1c.append(list_2[place])
place += 1