Python - 比较子列表中的第一项,如果重复,则比较第三项并选择较小的值

时间:2015-06-01 23:08:57

标签: python list set compare sublist

所以我有一个列表,里面有子列表。

例如

biglist = [['Red', 'Hi', 'There', '0.534'], ['Blue', 'Hello', 'Friend', '1.5'], 
['Blue', 'Yo', 'Dude', '1.2'], ['Green', 'Bon', 'Jour', '0.1'], 
['Purple', 'Hey', 'Sup', '0.4'], ['Purple', 'Greetings', 'Pal', '2.8']]

这就是我想要做的......我想迭代这个来做以下事情:

  • 对于每个子列表,请阅读位置0.
  • 如果在位置0处有另一个具有相同字符串的子列表,则读取位置3
  • 无论位置3中的哪个数字较低,请完全删除其他子列表,并使子列表保持较小的值。有时候有两个以上的子列表具有相同的位置[0]

所以,对于我的示例列表。我想保留红色'子列表,比较两个' Blue'子列表并将具有较小数值的那个保留在特定位置3,然后保持“绿色”状态。子表。我一直在乱搞set()但是有点难过。起初我尝试将它散列到0位置(红色,蓝色等)是键的位置,其余位置是值(作为列表)但是我卡住了并且走了不同的路线。

期望的结果:

biglist = [['Red', 'Hi', 'There', '0.534'], ['Blue', 'Yo', 'Dude', '1.2'], 
['Green', 'Bon', 'Jour', '0.1'], ['Purple', 'Hey', 'Sup', '0.4']]

要注意:我正在使用的列表正由前一个函数传递。

我在另一个问题上发现了这一点,但是set()让我感到困惑,我不知道如何进一步研究第三个位置或者如何正确地通过我已经通过另一个创建的列表在同一个脚本中使用此函数之前的函数。当我在尝试传递列表的同时运行它时,我什么也没得到。

def unique_items(L):
found = set()
for item in L:
    if item[0] not in found:
        yield item
        found.add(item[0])

非常感谢你。

3 个答案:

答案 0 :(得分:2)

首先,我将创建一个列表字典,其中子列表(颜色)中的第一个项目为键,值为元组(列表中的子列表索引,子列表中的最后一项):

from collections import defaultdict
x = defaultdict(list)

# This for loop extracts the index of each sublist (i) and then
# assigns the contents of the sublist to variables, in this case
# we want the first item in the sublist to be the 'key', ignore
# everything in between and grab the last item as the 'val'.
# If the sublists have arbitrary number of items then you could
# use for i, item in enumerate(biglist) and replace key with
# item[0] and val with item[3]
for i, (key, *_, val) in enumerate(biglist):
    x[key].append((i, float(val))

x现在看起来像:

defaultdict(<class 'list'>, {'Blue': [(1, '1.5'), (2, '1.2')], 'Purple': [(4, '0.4'), (5, '2.8')], 'Green': [(3, '0.1')], 'Red': [(0, '0.534')]})

然后我会按

创建一个新列表
  • 按字典x中的每种颜色的条目按升序排序,以便列表中的第一项是具有最小&#34;权重&#34;的项目。价值(你所谓的位置3
  • 获取该排序列表的第一项,该列表是包含子列表索引作为其第一项的元组
  • 最后使用索引
  • 检索子列表

类似于:

res = [biglist[sorted(val, key=lambda x: x[1])[0][0]] for val in x.values()]

res现在包含

[['Blue', 'Yo', 'Dude', '1.2'],
 ['Purple', 'Hey', 'Sup', '0.4'],
 ['Green', 'Bon', 'Jour', '0.1'],
 ['Red', 'HiThere', '0.534']]

答案 1 :(得分:1)

这是另一种方法 - 我认为更具可读性

# result_list for verification
result_list = [['Red', 'Hi', 'There', '0.534'], ['Blue', 'Yo', 'Dude', '1.2'], ['Green', 'Bon', 'Jour', '0.1'], ['Purple', 'Hey', 'Sup', '0.4']]

# original list 
biglist = [['Red', 'Hi', 'There', '0.534'], ['Blue', 'Hello', 'Friend', '1.5'], ['Blue', 'Yo', 'Dude', '1.2'], ['Green', 'Bon', 'Jour', '0.1'],
['Purple', 'Hey', 'Sup', '0.4'], ['Purple', 'Greetings', 'Pal', '2.8']]

another_list = []

import itertools

# Sort the big list by tuple of x[0], x[3] First sort by x[0] and then resolve tie by x[3]
biglist = sorted(biglist, key=lambda x:(x[0],x[3]))

# now group the list by the first element of each list, y gives an iterator, we simply make a list of that and take first element.

for x, y in itertools.groupby(biglist, lambda x:x[0]):
    another_list.append(list(y)[0])

# following line is just for verification
print another_list == sorted(result_list)

注意:此处不保留原始列表中的顺序。如果您希望保留它,请执行以下操作

 result_list = [['Red', 'Hi', 'There', '0.534'], ['Blue', 'Yo', 'Dude', '1.2'],
['Green', 'Bon', 'Jour', '0.1'], ['Purple', 'Hey', 'Sup', '0.4']]
biglist = [['Red', 'Hi', 'There', '0.534'], ['Blue', 'Hello', 'Friend', '1.5'],
['Blue', 'Yo', 'Dude', '1.2'], ['Green', 'Bon', 'Jour', '0.1'],
['Purple', 'Hey', 'Sup', '0.4'], ['Purple', 'Greetings', 'Pal', '2.8']]

#print sorted(sorted(biglist), key=lambda x:(x[0],x[3]))
cleanup_list = []
import itertools
s_biglist = sorted(biglist, key=lambda x:(x[0],x[3]))

for x, y in itertools.groupby(s_biglist, lambda x:x[0]):
    cleanup_list.extend(list(y)[1:])

for x in cleanup_list:
    biglist.remove(x)

print biglist

答案 2 :(得分:0)

非常感谢大家!这就是我以自己的方式解决它的方式。也许这不是最好的方式,我知道我的变量没有被命名为最好的(我实际上在这个例子中有目的地将它们命名为简单化,但对于我的真实脚本,它们是特定且独特的)。实际输入列表来自长度超过50,000行的文件。

#!/usr/bin/python

from collections import defaultdict

biglist = [['Red', 'Hi', 'There', '0.534'], ['Blue', 'Hello', 'Friend', '1.5'], 
['Blue', 'Yo', 'Dude', '1.2'], ['Green', 'Bon', 'Jour', '0.1'], 
['Purple', 'Hey', 'Sup', '0.4'], ['Purple', 'Greetings', 'Pal', '2.8']]

x = defaultdict(list)
for item in biglist:
    x[item[0]].append(item[1:])

y = dict(x)

for key, value in y.items():
    FINAL = []
    if len(value) <= 1:
        FINAL.append(value)
    else:
        valuelist = []
        for version in value:
            valuelist.append(version[3])
            best = min(valuelist)
        for version in value:
            if version[3] == best:
                FINAL.append(version)
        y[key] = FINAL
print y