如果要重复tuple [0:2],我想向tuple添加元组值,如下所示:

时间:2018-11-18 15:39:25

标签: python list tuples

我在这里有清单

some_list = [('A','B','IP1','N1'),('A','B','IP3','N3'),('B','C','IP2','N2'),('B','C','IP3','N3'),('D','F','IP4','N4')]

假设'A','B'('A','B','IP1','N1'),('A','B','IP3','N3')中 那么我们需要将两个元组合并为一个元组,并在('A','B','IP1','N1'),('A','B','IP3','N3')

中将('A','B','IP1','N1','IP3','N3')替换为some_list

结果:

some_list = [('A','B','IP1','N1','IP3','N3'), ('B','C','IP2','N2','IP3','N3'), ]

应该出现,但要确保代替“ A”,“ B”,“ C” ..每次都不会一样

你能帮我吗?

3 个答案:

答案 0 :(得分:2)

基本上,您需要为两个值创建一个元组键,并使用该值创建默认字典。

为每个键扩展列表的其余部分,然后通过将键(作为列表)添加到值,将键/值对转换回列表列表。

像这样:

import collections

some_list = [('A','B','IP1','N1'),('A','B','IP3','N3'),('B','C','IP2','N2'),('B','C','IP3','N3'),('D','F','IP4','N4')]

c = collections.defaultdict(list)
for k1,k2,*b in some_list:   # extended iterable unpacking allows this
    c[(k1,k2)].extend(b)  # add to existing list or create a new one

result = [a+tuple(b) for a,b in c.items()]

结果:

>>> result
[('D', 'F', 'IP4', 'N4'),
 ('B', 'C', 'IP2', 'N2', 'IP3', 'N3'),
 ('A', 'B', 'IP1', 'N1', 'IP3', 'N3')]

for k1,k2,*b in some_list部分允许将两个第一个值放在单独的k1k2变量中,而“ rest”放在b列表中。该功能在python 2中不可用。Python2用户可以使用更基本的替换循环:

for a in some_list:
    c[tuple(a[:2])].extend(a[2:])  # add to existing list or create a new one

(此问题与核心部分的问题Merge tuples with the same key类似,但前/后处理使其有所不同)

答案 1 :(得分:0)

您还可以使用itertools.groupby()将元组按前两个项目进行分组,然后将其余元组的末尾进行拼合:

from itertools import groupby
from itertools import chain
from pprint import pprint


some_list = [
    ("A", "B", "IP1", "N1"),
    ("A", "B", "IP3", "N3"),
    ("B", "C", "IP2", "N2"),
    ("B", "C", "IP3", "N3"),
    ("D", "F", "IP4", "N4"),
]

# key -> first two, rest -> everything after first two
key, rest = lambda x: x[:2], lambda x: x[2:]

pprint(
    [
        list(chain.from_iterable((k, *tuple(map(rest, g)))))
        for k, g in groupby(sorted(some_list, key=key), key=key)
    ]
)

其中给出以下内容:

[['A', 'B', 'IP1', 'N1', 'IP3', 'N3'],
 ['B', 'C', 'IP2', 'N2', 'IP3', 'N3'],
 ['D', 'F', 'IP4', 'N4']]

以上方法使用itertools.chain.from_iterable()来平整已分组的元组。您还需要按前两个项目对元组列表进行排序,以便将它们与itertools.groupby()进行分组。这是因为它将可迭代项中的连续键分组,这只能通过排序来实现。

此外,如果元组列表的长度始终为4,并且键始终为前两个项,则还可以对keyrest使用operater.itemgetter()

from operator import itemgetter
key, rest = itemgetter(0, 1), itemgetter(2, 3)

查找前两个值(0,1)和后两个值(2,3)

答案 2 :(得分:0)

您也可以尝试以下代码。

>>> def get_combined_items(tup1, tup2):
...     l = list(tup1)
...     for item in tup2:
...         if item not in l:
...             l.append(item)
...     return l
...
>>>
>>> if len(some_list) % 2 == 0: # even number of items
...     some_list = [tuple(get_combined_items(some_list[i], some_list[i + 1])) for i in range(0, len(some_list) - 1, 2)]
... else:
...     last_item = some_list[-1] # save last item
...     some_list = [tuple(get_combined_items(some_list[i], some_list[i + 1])) for i in range(0, len(some_list) - 1, 2)]
...     some_list = some_list + [last_item]
...
>>> some_list
[('A', 'B', 'IP1', 'N1', 'IP3', 'N3'), ('B', 'C', 'IP2', 'N2', 'IP3', 'N3'), ('D', 'F', 'IP4', 'N4')]
>>>

如果要尝试使用第三方软件包,请使用ordered-set安装pip install ordered-set

  

»pip安装命令集

您可以选中https://pypi.org/project/ordered-set/

  

注意:这只是为了在将组合的元组传递到set()之后使元素保持顺序。

>>> from ordered_set import OrderedSet
>>>
>>> some_list = [('A','B','IP1','N1'),('A','B','IP3','N3'),('B','C','IP2','N2'),('B','C','IP3','N3'),('D','F','IP4','N4')]
>>>
>>> if len(some_list) % 2 == 0: # even number of items
...     some_list = [tuple(OrderedSet(some_list[i] + some_list[i + 1])) for i in range(0, len(some_list) - 1, 2)]
... else:
...     last_item = some_list[-1] # save last item
...     some_list = [tuple(OrderedSet(some_list[i] + some_list[i + 1])) for i in range(0, len(some_list) - 1, 2)]
...     some_list = some_list + [last_item]
...
>>>
>>> some_list
[('A', 'B', 'IP1', 'N1', 'IP3', 'N3'), ('B', 'C', 'IP2', 'N2', 'IP3', 'N3'), ('D', 'F', 'IP4', 'N4')]
>>>