简体   繁体   中英

Truncate sublists to the lowest length

I have:

l = [[1,2,3],[3,4],[1,6,8,3]]

I want:

[[1,2],[3,4],[1,6]]

Which is the list l with all sublists truncated to the lowest length found for the sublists in l .

I tried:

min = 1000

for x in l:
    if len(x) < min: min = len(x)

r = []

for x in l:
    s = []
    for i in range(min):
        s.append(x[i])
    r.append(s.copy())

Which works but quite slow and long to write. I'd like to make this more efficient through list comprehension or similar.

You can find the length of each item in the list and then pick min element from it. Later you can use this value to truncate all the items in the list

l = [[1,2,3],[3,4],[1,6,8,3]]
min_length  = min(map(len,l)) # using map with len function to get the length of each item and then using min to find the min value.
l = [item[:min_length] for item in l] # list comprehension to truncate the list

One liner -


l = [item[:min(map(len,l))] for item in l] 

One fun thing about zip is zip is the inverse itself, so list(zip(*zip(*x))) gives x in similar structure.
And zip stop iteration when any input is exhausted.

Though the results are tuple s and the nested lists are not truncated in-place., one can make use of this to build the following output:

Output:

[(1, 2), (3, 4), (1, 6)]
l = [[1, 2, 3], [3, 4], [1, 6, 8, 3]]

print(list(zip(*zip(*l))))

Using del :

n = min(map(len, l))
for a in l:
    del a[n:]

With list comprehension, one-liner:

l = [[1,2,3],[3,4],[1,6,8,3]]

print ([[s[i] for i in range(min([len(x) for x in l]))] for s in l])

Or:

print ([s[:min([len(s) for s in l])] for s in l])

Output:

[[1, 2], [3, 4], [1, 6]]

We compute the minimal length of subslists in the 'range()' to iterate over sublists for that amount and to reconstruct a new subslist. The top-level list comprehension allows to reconstruct the nested sublist.

If you have a large nested list, you should use this version with two lines:

m = min([len(x) for x in l])

print ([[s[i] for i in range(m)] for s in l])

Or:

print ([s[:m] for s in l])

Using zip and preserving the list objects:

print (list([list(x) for x in zip(*zip(*l))]))

Output:

[[1, 2], [3, 4], [1, 6]]

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