我想做以下事情:
1]将列表a中的每个元素与b进行比较并映射相似的值。
a=[1, 2, 3, 6, 4, 5, 7, 8, 9]
b=[4, 4, 5, 5, 7, 7, 9, 9, 10]
我试过以下:
c = set(a) & set(b)
>>> set([9,4,5,7])
2]我希望这些映射值的编号顺序与列表b中的编号顺序相同,例如4,5,7,9。
3]最后我想使用这些键值(4,5,7,9)并从列表a生成相应的值,例如:
4 (1,2)
5 (3,6)
7 (4,5)
9 (7,8)
任何建议都会非常感激?
答案 0 :(得分:2)
要解决您的问题3
,您需要将每个列表与对方集进行比较。这将自动解决您的#2。
还有其他方法可以解决#2,比如使用OrderedSet(比如recipe中链接到的collections
docs),但由于它们无法解决#3,所以没有必要进入这一点。
如果a
值非常大,您可能希望构建索引结构 - 将值映射到索引集合的字典 - 以使其更快。像这样:
rev_a = collections.defaultdict(list)
for index, value in enumerate(a):
rev_a[value].append(index)
然后查找部分变得更容易,更快:
for b_value in b:
a_indices = rev_a[b_value]
if a_indices:
a_str = ','.join(map(str, a_indices))
print('{} is associated with ({})'.format(b_value, a_str))
或者,如果你想创建某种结构而不是即时打印:
results = [(b_value, rev_a[b_value]) for b_value in b]
results = OrderedDict((b_value, rev_a[b_value]) for b_value in b)
# etc.
这实际上并没有产生你要求的输出,但是......我不确定你要求的输出应该是什么来的。除非您从其他列表中获取匹配的索引,然后在第一个列表中查找它们?这至少是奇怪的。无论如何,像这样的索引结构应该使得实现你提出的任何规则变得微不足道,即使是更奇怪的规则,只要你能够解释它。
例如,将a_str
行替换为:
a_str = ','.join(str(a[a_index] for index in a_indices))
...你得到了你想要的输出。
答案 1 :(得分:2)
现在您已经更新了问题,我发现您真正想要的只是价值键的映射:
a = [1, 2, 3, 6, 4, 5, 7, 8, 9]
b = [4, 4, 5, 5, 7, 7, 9, 9, 10]
r = dict([(x, []) for x in b])
for k, v in zip(b, a):
r[k] += [v,]
以下是如何使用结果:
>>> for k, v in r.items():
... print k, v
...
9 [7, 8]
10 [9,]
4 [1, 2]
5 [3, 6]
7 [4, 5]
>>>
>>> print r[4]
[1, 2]
这是一个优化版本,可以更快地运行,内存使用量更少:
from itertools import izip
from collections import defaultdict
r = defaultdict(list)
for k, v in izip(b, a):
r[k] += [v]
答案 2 :(得分:0)
您可以使用list comprehension
>>> a=[1, 2, 3, 6, 4, 5, 7, 8, 9]
>>> b=[4, 4, 5, 5, 7, 7, 9, 9, 10]
>>> [x for x in a if x in b]
[4, 5, 7, 9]