说我有这个清单
A = [['a','b'],
['b','c'],
['c','a'],
['d','a'],
['e',None]]
匹配元素的最佳/有效方法是什么,以便您可以找出列表中第一个和第二个元素之间匹配的列表。
预期比赛将是:
如图所示,在一个列表中可以有更多匹配,并且可以存在与任何值不匹配的None值。列表中的列表中还有其他项目,但此示例不需要。每个列表中的第一个和第二个项目不匹配。我想在每次匹配时运行一些东西,并且需要一种简单的方法来做到这一点。
这是否有意义并且可行?
答案 0 :(得分:3)
创建从第一个元素到索引的映射。我假设第一个元素是唯一的,以简化这个例子:
indices = {t[0]: i for i, t in enumerate(A)}
现在,您可以简单地将每个元素映射到与其匹配的索引:
for index, (first, second) in enumerate(A):
if second in indices:
print(f'Row {index} matches row {indices[second]}')
演示:
>>> A = [['a','b'],
... ['b','c'],
... ['c','a'],
... ['d','a'],
... ['e',None]]
>>> indices = {t[0]: i for i, t in enumerate(A)}
>>> for index, (first, second) in enumerate(A):
... if second in indices:
... print(f'Row {index} matches row {indices[second]}')
...
Row 0 matches row 1
Row 1 matches row 2
Row 2 matches row 0
Row 3 matches row 0
答案 1 :(得分:0)
你所看到的图表边缘列表以及你想要找出的是它们是否已连接(即它们有共同点)。
您还有一个有向图,边缘的顺序为您的"匹配" (根据您的定义,它不是对称的)。
edge = [['a','b'],
['b','c'],
['c','a'],
['d','a'],
['e',None]]
# order of edges doesn't count
def is_connected(e1, e2):
return e1[0] == e2[1] or e1[1] == e2[0]
# order of edges counts
def is_child(e1, e2):
return e1[1] == e2[0]
你想要的是第二次检查is_child
,我假设
print(is_connected(edge[0],edge[1]))
print(is_connected(edge[1],edge[2]))
print(is_connected(edge[0],edge[2]))
print(is_child(edge[0],edge[1]))
print(is_child(edge[1],edge[2]))
print(is_child(edge[0],edge[2])) # false
print(is_child(edge[2],edge[0]))
如果你想检查图中所有边缘的这种类型的定向连接,你基本上想要按第二个坐标分组,并在pandas中有一个方便的函数groupby
来做到这一点:
import pandas as pd
df = pd.DataFrame(edge)
grouped = df.groupby(1)
grouped.groups
# Output:
{'a': [2L, 3L], 'c': [1L], 'b': [0L]}
grouped.groups['a']
# Output:
# [2L, 3L]
grouped[0].apply(lambda x: ','.join(x)).reset_index()
# Output:
# 1 0
# 0 a c,d
# 1 b a
# 2 c b