我在这里有清单
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” ..每次都不会一样
你能帮我吗?
答案 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
部分允许将两个第一个值放在单独的k1
和k2
变量中,而“ 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,并且键始终为前两个项,则还可以对key
和rest
使用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')]
>>>