简体   繁体   中英

Compare 1st element in list of lists and write number of repeated values

I have list of lists that looks like this:

fails = [['55','35325235432','log'], ['55','22222222','log'], ['55','3232432','log2'], ['64','55','log3'], ['64','324234324','log2']]

I need to compare 1st value in inner lists (here it's '55' and '64') and if it is repeated in other lists, that repeated lists should be deleted. But number of that repeated values should be added to first list.

So at the and it should looks like this:

shorten_fails = [['55','35325235432','log','3'], ['64','55','log3', '2']]

First list with unique value is preserved and number of lists with this value at the 1st position is added.

I was trying to do this by looping but at the end I finished with for in for in for in for... and I'm sure there must be an easier way to do that

You could make use of Python's Counter and OrderedDict features as follows:

from collections import Counter, OrderedDict

fails = [['55','35325235432','log'], ['55','22222222','log'], ['55','3232432','log2'], ['64','55','log3'], ['64','324234324','log2']]

v1_counts = Counter(v[0] for v in fails)
v1 = OrderedDict({v[0] : v for v in fails})
shorten_fails = [v + [v1_counts[k]] for k, v in v1.items()]

print shorten_fails

This would display the following output:

[['55', '3232432', 'log2', 3], ['64', '324234324', 'log2', 2]]

v1_counts holds a count of all of the values, ie

Counter({'55': 3, '64': 2})

v1 holds the last entry of each value, ie

OrderedDict([('55', ['55', '3232432', 'log2']), ('64', ['64', '324234324', 'log2'])])

Finally shorten_fails is constructed by taking the v1 entries and appending the corresponding counter value to each element.

fails = [['55','35325235432','log'], ['55','22222222','log'], ['55','3232432','log2'], ['64','55','log3'], ['64','324234324','log2']]

first_elems = set(fail[0] for fail in fails)
new_fails = []
for fail in fails:
    first = fail[0]
    if first in first_elems:
        new_fails.append(fail + [sum(f[0] == first for f in fails)])
        first_elems.remove(first)

print(new_fails)
# [['55', '35325235432', 'log', 3], ['64', '55', 'log3', 2]]

You could use a dictionary as lookup table to store the indices of the elements you've already added to the shortened list:

def shorten(fails):
    sf, ind = [], {}
    for el in fails:
        if el[0] in ind:
            sf[ind[el[0]]][-1] += 1
        else:
            ind[el[0]] = len(sf)
            sf.append(el + [1])
    return sf

>>> shorten(fails)
[['55', '35325235432', 'log', 3], ['64', '55', 'log3', 2]]

If you really want the counter to be a string, you can easily do the conversion of the last list element at the end.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM