从字典构建对

时间:2017-11-04 16:32:30

标签: python python-3.x

我的数据是各国人民的嵌套说明。这里有不重要的东西被移除后的样子:

{'DE': [{'createdTime': '2017-11-03T13:41:01.000Z',
         'fields': {'Land': 'DE', 'Teilnehmer': 'James Hunt'},
         'id': 'reccgdSZXZFvAztCT'},
        {'createdTime': '2017-11-04T12:50:21.000Z',
         'fields': {'Land': 'DE', 'Teilnehmer': 'Susie Mueller'},
         'id': 'recQhmPmTrlZzoI84'},
        {'createdTime': '2017-11-04T12:50:33.000Z',
         'fields': {'Land': 'DE', 'Teilnehmer': 'Tom Tikky'},
         'id': 'recKCh99xvQwwCmSp'}],
 'UK': [{'createdTime': '2017-11-03T13:41:01.000Z',
         'fields': {'Land': 'UK', 'Teilnehmer': 'John Doe'},
         'id': 'recFTlSMXNET6e2UX'},
        {'createdTime': '2017-11-03T14:16:00.000Z',
         'fields': {'Land': 'UK', 'Teilnehmer': 'Jane Smith'},
         'id': 'recLqDHWh14TLm30g'},
        {'createdTime': '2017-11-03T18:41:56.000Z',
         'fields': {'Land': 'UK', 'Teilnehmer': 'Claire Singer'},
         'id': 'recB8XaFb7va0lT50'}]}

之前已按国家/地区排序。我现在需要建立发送者/接收者对,每个人都需要两对 - 一次作为发送者,一次作为接收者。双方都需要来自同一个国家。因此,根据上面的样本数据,最后每个国家将有3对。

输出上最重要的是id。基本上我认为列表可以在输出中起作用,但我不确定这些列表中的元素顺序是否可靠。除此之外,结果可能是这样的:

[
    # DE Pairs
    ['reccgdSZXZFvAztCT', 'recQhmPmTrlZzoI84'],
    ['recQhmPmTrlZzoI84', 'recKCh99xvQwwCmSp'],
    ['recKCh99xvQwwCmSp', 'reccgdSZXZFvAztCT'],
    # UK Pairs
    ['recFTlSMXNET6e2UX', 'recLqDHWh14TLm30g'],
    ['recLqDHWh14TLm30g', 'recB8XaFb7va0lT50'],
    ['recB8XaFb7va0lT50', 'recFTlSMXNET6e2UX']
]

我想到的所有解决这个问题的方法都涉及几个级别的for循环,但我仍然没有设法完成它。我非常肯定必须有一种pythonic方法来解决这个问题。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

from itertools import combinations

d = {
    'DE': [{'createdTime': '2017-11-03T13:41:01.000Z',
     'fields': {'Land': 'DE', 'Teilnehmer': 'James Hunt'},
     'id': 'reccgdSZXZFvAztCT'},
    {'createdTime': '2017-11-04T12:50:21.000Z',
     'fields': {'Land': 'DE', 'Teilnehmer': 'Susie Mueller'},
     'id': 'recQhmPmTrlZzoI84'},
    {'createdTime': '2017-11-04T12:50:33.000Z',
     'fields': {'Land': 'DE', 'Teilnehmer': 'Tom Tikky'},
     'id': 'recKCh99xvQwwCmSp'}],
    'UK': [{'createdTime': '2017-11-03T13:41:01.000Z',
     'fields': {'Land': 'UK', 'Teilnehmer': 'John Doe'},
     'id': 'recFTlSMXNET6e2UX'},
    {'createdTime': '2017-11-03T14:16:00.000Z',
     'fields': {'Land': 'UK', 'Teilnehmer': 'Jane Smith'},
     'id': 'recLqDHWh14TLm30g'},
    {'createdTime': '2017-11-03T18:41:56.000Z',
     'fields': {'Land': 'UK', 'Teilnehmer': 'Claire Singer'},
     'id': 'recB8XaFb7va0lT50'}]}
l = [list(combinations((x['id'] for x in v), 2)) for v in d.values()]

给我们

[[('recFTlSMXNET6e2UX', 'recLqDHWh14TLm30g'),
  ('recFTlSMXNET6e2UX', 'recB8XaFb7va0lT50'),
  ('recLqDHWh14TLm30g', 'recB8XaFb7va0lT50')],
 [('reccgdSZXZFvAztCT', 'recQhmPmTrlZzoI84'),
  ('reccgdSZXZFvAztCT', 'recKCh99xvQwwCmSp'),
  ('recQhmPmTrlZzoI84', 'recKCh99xvQwwCmSp')]]

编辑:

results = []
for country in d.values():
    ids = [people['id'] for people in country]
    rotated_ids = ids[1:] + ids[:1]
    for a, b in zip(ids, rotated_ids):
        results.append([a, b])

会给我们更像

的东西
[['recFTlSMXNET6e2UX', 'recLqDHWh14TLm30g'],
 ['recLqDHWh14TLm30g', 'recB8XaFb7va0lT50'],
 ['recB8XaFb7va0lT50', 'recFTlSMXNET6e2UX'],
 ['reccgdSZXZFvAztCT', 'recQhmPmTrlZzoI84'],
 ['recQhmPmTrlZzoI84', 'recKCh99xvQwwCmSp'],
 ['recKCh99xvQwwCmSp', 'reccgdSZXZFvAztCT']]

答案 1 :(得分:1)

至少,如果一个国家/地区的人数大于2,那么不仅仅有一种方法可以生成您想要的对。因此,您需要选择一种方法来选择对这样每个人的每一端都只有一次。

一种简单的方法是让每个人在国家列表中发送给他们之后的人。换行,以便最后一个人发送到第一个,你有一个工作算法。

这是一个列表理解,我认为你做了你想做的事情:

result = [(p[i-1]['id'], p[i]['id']) for p in data.values() for i in range(len(p))]

在理解中,p是代表来自单个国家/地区的人的词典列表,ip的索引。我们允许i-1在开始时为-1,因为它处理"环绕"我们需要按照你想要的方式工作。