Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何通过删除重复项和移动值从现有列表中创建新列表?_Python_List - Fatal编程技术网

Python 如何通过删除重复项和移动值从现有列表中创建新列表?

Python 如何通过删除重复项和移动值从现有列表中创建新列表?,python,list,Python,List,如果我有以下列表要开始: list1 = [(12, "AB"), (12, "AB"), (12, "CD"), (13, Null), (13, "DE"), (13, "DE")] 我想将其转换为以下列表: list2 = [(12, "AB", "CD"), (13, "DE", Null)] 基本上,如果有一个或多个文本值及其关联键,则第二个列表首先有键值,然后是一个文本值,然后是另一个。如果没有第二个字符串值,则如果第二个列表为空,则为项目中的第三个值 我在脑子里一遍又一遍地思考

如果我有以下列表要开始:

list1 = [(12, "AB"), (12, "AB"), (12, "CD"), (13, Null), (13, "DE"), (13, "DE")]
我想将其转换为以下列表:

list2 = [(12, "AB", "CD"), (13, "DE", Null)]
基本上,如果有一个或多个文本值及其关联键,则第二个列表首先有键值,然后是一个文本值,然后是另一个。如果没有第二个字符串值,则如果第二个列表为空,则为项目中的第三个值

我在脑子里一遍又一遍地思考这个问题,不知道该怎么做。使用set()将减少精确的重复项,但是如果键值相同,则必须进行某种上一个/下一个操作来比较第二个值


我不使用字典的原因是键值的顺序必须保持不变(12、13等)。

我能看到的最简单的方法是:

>>> from collections import OrderedDict

>>> d = OrderedDict()
>>> for (k, v) in [(12, "AB"), (12, "AB"), (12, "CD"), (13, None), (13, "DE"), (13, "DE")]:
...     if k not in d: d[k] = set()
...     d[k].add(v)

>>> d
OrderedDict([(12, {'AB', 'CD'}), (13, {'DE', None})])
或者,如果您想要列表(这也将保持值顺序),并且不介意效率稍低一点(因为
v not in…
测试必须扫描列表):

最后,您可以使用以下命令将其转换回列表:

>>> list(d.items())
[(12, ['AB', 'CD']), (13, [None, 'DE'])]
>>> [[k] + d[k] for k in d]
[[12, 'AB', 'CD'], [13, None, 'DE']]
>>> [(k,) + tuple(d[k]) for k in d]
[(12, 'AB', 'CD'), (13, None, 'DE')]
具体取决于您想要的格式


[对不起,前面的评论和回复误解了这个问题。]

我能看到的最简单的方法是:

>>> from collections import OrderedDict

>>> d = OrderedDict()
>>> for (k, v) in [(12, "AB"), (12, "AB"), (12, "CD"), (13, None), (13, "DE"), (13, "DE")]:
...     if k not in d: d[k] = set()
...     d[k].add(v)

>>> d
OrderedDict([(12, {'AB', 'CD'}), (13, {'DE', None})])
或者,如果您想要列表(这也将保持值顺序),并且不介意效率稍低一点(因为
v not in…
测试必须扫描列表):

最后,您可以使用以下命令将其转换回列表:

>>> list(d.items())
[(12, ['AB', 'CD']), (13, [None, 'DE'])]
>>> [[k] + d[k] for k in d]
[[12, 'AB', 'CD'], [13, None, 'DE']]
>>> [(k,) + tuple(d[k]) for k in d]
[(12, 'AB', 'CD'), (13, None, 'DE')]
具体取决于您想要的格式


[很抱歉,前面的评论和回复误解了这个问题。]

一种简单的方法将在
列表1中循环多次,每次都获取相关值。第一次抓住所有的钥匙。然后,获取每个键的所有值():

如果您想提高性能,我会使用字典作为中间工具,这样您就不必多次遍历
list1


一种简单的方法是多次循环
list1
,每次都获取相关的值。第一次抓住所有的钥匙。然后,获取每个键的所有值():

如果您想提高性能,我会使用字典作为中间工具,这样您就不必多次遍历
list1


我更愿意使用排序的dict或外部订单列表[12,13等]来记住添加的订单键。好的,如果我们使用OrderedDict(感谢您指出这是存在的),我仍然不知道如何创建新的dict,删除重复的值,并按照我需要的方式排列。字符串的顺序重要吗?即“CD”之前的“AB”?Jared:顺序不重要,但如果有空值,则必须是第二个。我宁愿使用排序dict或外部顺序列表[12,13,等等]An会记住添加的顺序键。好吧,如果我们使用OrderedDict(感谢您指出它的存在),我仍然不知道如何创建新的dict,删除重复的值,并按照我需要的方式排列。字符串的顺序重要吗?例如,“CD”之前的“AB”?Jared:顺序不重要,但如果有空值,它必须是第二个。太棒了,我会试试这个。非常感谢。太棒了,我要试试这个。非常感谢。
from collections import defaultdict 
Null = None
list1 = [(12, "AB"), (12, "AB"), (12, "CD"), (13, Null), (13, "DE"), (13, "DE")]

keys = []
for k,v in list1:
    if k not in keys:
        keys.append(k)

intermediate = defaultdict(list)
for k, v  in list1:
    if v not in intermediate[k]:
        intermediate[k].append(v)

list2 = []
for k in keys:
    list2.append([k] + intermediate[k])

print(list2)
from collections import defaultdict

pairs = [(12, "AB"), (12, "AB"), (12, "CD"),
         (13, None), (13, "DE"), (13, "DE")]

result = defaultdict(set)
for k,v in pairs:
    result[k].add(v)

result = [(k,) + tuple(reversed(sorted(vs))) for k,vs in result.iteritems()]