简体   繁体   中英

Sorting elements from a list of tuples into two separate lists

As the title says I'm in the process of sorting tagged elements into two lists. My current code for this is:

lst = [("foo", "good"), ("bar", "bad")...("x", "n")]

def sort(items):
    good = []
    bad = []
    for i in range(len(items)):
        if items[i][1] == 'good':
            good += items[i][0]
        else:
            bad += items[i][0]
    return good, bad


alpha, beta = sort(lst)

My output is simply f . I've been trying to work this out for a while but the solution has been eluding me. Any suggestions?

Thank you all.

You can fix your code:

def sort(items):
    good = []
    bad = []
    for x, y in items:
        if y == 'good':
            good.append(x)
        else:
            bad.append(x)
    return good, bad

Note that += corresponds to list.extend which adds iterables element-wise. For strings that means char by char.

To create new lists with mapping or filtering, it's often shorter and easier to read to use list comprehensions rather than calling .append in a loop:

data = [("foo", "good"), ("bar", "bad"), ("head", "good"), ("tails", "bad"), ("x", "n")]

good_lst = [x for x,quality in data if quality == 'good']
bad_lst = [x for x,quality in data if quality != 'good']

print(good_lst)
# ['foo', 'head']
print(bad_lst)
# ['bar', 'tails', 'x']

Your code is fine, but you need to change one thing:

items[i][0] -> [items[i][0]]

When you want to use + you need to have values as list:

>>> [2,3] + [4]
[2,3,4]

Your code with one change:

lst = [("foo", "good"), ("bar", "bad"), ("head", "good"), ("tails", "bad")]

def sort(items):
    good = []
    bad = []
    for item in items:
        if item[1] == 'good':
            good += [item[0]]
        else:
            bad += [item[0]]
    return good, bad


alpha, beta = sort(lst)
print (alpha, beta)

Output:

['foo', 'head'] ['bar', 'tails']

You can try to solve this in a cleaner way using list comprenhension to compute both lists:

def sort(items):
    good = [items[idx][0] for idx in range(0,len(items)) if items[idx][1] == 'good']
    bad = [items[idx][0] for idx in range(0,len(items)) if items[idx][1] == 'bad']

    return good, bad

If performance is not an issue this could be better due to it is a declarative approach instead of an imperative one so it could be easier to read, but takes into account that it iterates the list twice.

Hopes it helps you!

+= is used when you try to add LHS to RHS with same datatype. When you do good += items[i][0] it's like adding foo as a list ( ['f', 'o', 'o'] ) to the list good . That's the reason you see the behavior. Hence use list.append() to add element to a list. Try out this:

lst = [("foo", "good"), ("bar", "bad"), ("head", "good"), ("tails", "bad")]

def sort(items):
    good = []
    bad = []
    for item in items:
        #print (item, type(item))
        if item[1] == 'good':
            good.append(item[0])
        else:
            bad.append(item[0])
    return good, bad


alpha, beta = sort(lst)
print (alpha, beta)

Output:

['foo', 'head'] ['bar', 'tails']

I just changed good += items[i][0] to good.append(i[0])

lst = [("foo", "good"),("bar", "bad"),("x", "n")]

def sort(items):
    good = []
    bad = []
    for i in items:
        if i[1] == 'good':
            good.append(i[0])
        else:
            bad.append(i[0])
    return good, bad


alpha, beta = sort(lst)
print(alpha)
print(beta)

Output:

['foo']
['bar', 'x']

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