Python - 从两个列表中排序一个列表

时间:2018-04-21 21:27:18

标签: python list sorting tuples

我有两个要排序的列表。第一个列表包含id和流派字符串:

ids_and_genres = [
    (u'spotify:track:7ac8sivblLQjsQipO5FZ63', u'bossa nova'), 
    (u'spotify:track:4r8uJGqC1tB16592dPrJA8', u'sertanejo pop'), 
    (u'spotify:track:6A07yoIkMuRuMVHMlpKx5e', u'deep funk carioca'), 
    (u'spotify:track:6jPkYQ3B7b753JTZhR207H', u'rock gaucho'), 
    (u'spotify:track:5ggZKufUobrPQATp4URED4', u'rap'), 
    (u'spotify:track:2C5WKzZ28VrAnMRo7CaTDe', u'baile pop'), 
    (u'spotify:track:59UvKSCJLFDsGOSESlzfAg', u'samba'), 
    (u'spotify:track:4JWvILyOVmhPqXgSSjVB4p', u'brazilian reggae'), 
    (u'spotify:track:0cbbgNAPNI8ylaFE0te1yw', u'grime'), 
    (u'spotify:track:0ZoJ7jZBHY6SjhbClU7p2B', u'forro'), 
    (u'spotify:track:6Du0r4fahau45X9bkXIIjB', u'baile funk'), 
    (u'spotify:track:10KJMfYgg6CORIhtkPn04i', u'mpb'), 
    (u'spotify:track:2D6xFqZdBfdXndPQV4GBLm', u'brazilian hip hop'), 
    (u'spotify:track:3LO1I8lQSsXD6gVdU9KZA1', u'brazilian electronica'), 
    (u'spotify:track:34646YmFkOhjWcBLhLhIoC', u'pagode'), 
    (u'spotify:track:49usrgIx7kiHYIFWxzYgIC', u'sertanejo tradicional'), 
    (u'spotify:track:0gFm2Uv3wveMbcqbdNvr2N', u'hip hop tuga'), 
    (u'spotify:track:4UhSLr0vsqzV88uixMt7ca', u'brazilian punk'), 
    (u'spotify:track:0XcuBfglpHdhOoIdaSEjAv', u'brazilian rock'), 
    (u'spotify:track:6JRUorZc2SfckySosQKSkz', u'hip hop'), 
    (u'spotify:track:6xR9X79wQ2RGQCK0oBeSnt', u'axe'), 
    (u'spotify:track:6lGieRasxAycezIC93ofXM', u'sertanejo'), 
    (u'spotify:track:3QhJAGDdxt749dFveYVy4M', u'sertanejo universitario')
]

,第二个列表包含流派和其他值

genres_and_other_values = [
    ([u'mpb ', u' 3532', u' 808'], 306.413119823548), 
    ([u'samba ', u' 3622', u' 839'], 392.8612986793176), 
    ([u'forro ', u' 2987', u' 837'], 422.0011848324599), 
    ([u'sertanejo tradicional ', u' 2926', u' 875'], 493.62738983974543), 
    ([u'pagode ', u' 2753', u' 828'], 621.342095789429), 
    ([u'bossa nova ', u' 3980', u' 864'], 713.6504746723007), 
    ([u'sertanejo ', u' 2563', u' 801'], 791.6091207155208), 
    ([u'baile pop ', u' 2461', u' 917'], 925.3783010207231), 
    ([u'sertanejo universitario ', u' 2399', u' 812'], 952.9249708135474),
    ([u'rock gaucho ', u' 2337', u' 688'], 992.5693930401038), 
    ([u'brazilian rock ', u' 2281', u' 570'], 1043.0810131528615), 
    ([u'brazilian punk ', u' 2217', u' 389'], 1123.8705441464333), 
    ([u'axe ', u' 2186', u' 853'], 1169.5913816371938), 
    ([u'brazilian hip hop ', u' 2237', u' 1069'], 1190.699374317464), 
    ([u'sertanejo pop ', u' 2111', u' 805'], 1233.1475986271878), 
    ([u'hip hop tuga ', u' 1963', u' 971'], 1415.2261303410137), 
    ([u'hip hop ', u' 1974', u' 1088'], 1441.3622029177816), 
    ([u'rap ', u' 1773', u' 1076'], 1627.4673575835554), 
    ([u'deep funk carioca ', u' 1825', u' 1233'], 1633.86076518166), 
    ([u'grime ', u' 1556', u' 949'], 1805.4860841335776), 
    ([u'brazilian reggae ', u' 1509', u' 1235'], 1928.5561957070372), 
    ([u'baile funk ', u' 871', u' 1185'], 2525.7895795176605), 
    ([u'brazilian electronica ', u' 722', u' 1260'], 2688.6303204419905)
]

我想要排序成一个新列表,尊重第二个列表的顺序,最后得到:

sorted = [['mpb', u'spotify:track:10KJMfYgg6CORIhtkPn04i'],[...]]

我试过了,但无济于事:

for item in genres_and_other_values:
    values = item[0]
    genre = values[0]
    for i in ids_and_genres:
        gen = i[1]
        id_ = i[0]
        if genre == gen:
            print (genre,id_)

上面的代码段无声地失败了......

达到我想要的结果的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

您的数据需要重新组织。首先,我重建一个字典,其中id为键,类型为值(ids_and_genres列表的倒数)

然后我使用genres_and_other_values的第一项(剥离,删除额外空格)在该字典中执行有序查找

ids_and_genres_dict = {k:v for v,k in ids_and_genres}

rebuilt = [(k,ids_and_genres_dict[k]) for k in (x[0][0].strip() for x in genres_and_other_values)]

给出:

[('mpb', 'spotify:track:10KJMfYgg6CORIhtkPn04i'), ('samba', 'spotify:track:59UvKSCJLFDsGOSESlzfAg'), ('forro', 'spotify:track:0ZoJ7jZBHY6SjhbClU7p2B'),...

这个方法很简短,复杂性很小:O(n)(考虑到大部分时间字典查找都是O(1)

答案 1 :(得分:0)

列表a和列表b,返回列表c

a2=[]
for i in a:
    for j in i:
        a2.append(j)
b2=[]
for i in b:
    for j in i:
        b2.append(j)
idx=0
c=[]
for i in a2:
    c.append([i, b2[idx]])
    idx+=1

答案 2 :(得分:0)

您可以对两个列表进行间接排序,然后使用索引将一个列表重新排列到另一个列表中:

>>> from operator import itemgetter
>>> 
# extract relevant columns
>>> g1 = list(map(itemgetter(1), ids_and_genres))
>>> g2 = list(map(str.strip, map(itemgetter(0), map(itemgetter(0), genres_and_other_values))))
>>> 
>>> assert len(g1) == len(g2)
>>>
# indirectly sort
>>> o1 = sorted(range(len(g1)), key=g1.__getitem__)
>>> o2 = sorted(range(len(g2)), key=g2.__getitem__)
>>> 
# allocate and then fill the result
>>> result = len(g2) * [None]
# the loop traverses both result and ids_and_genres in alphabetical 
# o1 tells it where to find each element in ids_and_genres and o2
# tells it where that element should go
# this assumes that g1 and g2 have exactly the same elements
# the assertion double checks this
>>> for i1, i2 in zip(o1, o2):
...     assert g1[i1] == g2[i2]
...     result[i2] = ids_and_genres[i1][::-1]
... 
>>> 
>>> from pprint import pprint
>>> pprint(result)
[('mpb', 'spotify:track:10KJMfYgg6CORIhtkPn04i'),
 ('samba', 'spotify:track:59UvKSCJLFDsGOSESlzfAg'),
 ('forro', 'spotify:track:0ZoJ7jZBHY6SjhbClU7p2B'),
 ('sertanejo tradicional', 'spotify:track:49usrgIx7kiHYIFWxzYgIC'),
 ('pagode', 'spotify:track:34646YmFkOhjWcBLhLhIoC'),
 ('bossa nova', 'spotify:track:7ac8sivblLQjsQipO5FZ63'),
 ('sertanejo', 'spotify:track:6lGieRasxAycezIC93ofXM'),
 ('baile pop', 'spotify:track:2C5WKzZ28VrAnMRo7CaTDe'),
 ('sertanejo universitario', 'spotify:track:3QhJAGDdxt749dFveYVy4M'),
 ('rock gaucho', 'spotify:track:6jPkYQ3B7b753JTZhR207H'),
 ('brazilian rock', 'spotify:track:0XcuBfglpHdhOoIdaSEjAv'),
 ('brazilian punk', 'spotify:track:4UhSLr0vsqzV88uixMt7ca'),
 ('axe', 'spotify:track:6xR9X79wQ2RGQCK0oBeSnt'),
 ('brazilian hip hop', 'spotify:track:2D6xFqZdBfdXndPQV4GBLm'),
 ('sertanejo pop', 'spotify:track:4r8uJGqC1tB16592dPrJA8'),
 ('hip hop tuga', 'spotify:track:0gFm2Uv3wveMbcqbdNvr2N'),
 ('hip hop', 'spotify:track:6JRUorZc2SfckySosQKSkz'),
 ('rap', 'spotify:track:5ggZKufUobrPQATp4URED4'),
 ('deep funk carioca', 'spotify:track:6A07yoIkMuRuMVHMlpKx5e'),
 ('grime', 'spotify:track:0cbbgNAPNI8ylaFE0te1yw'),
 ('brazilian reggae', 'spotify:track:4JWvILyOVmhPqXgSSjVB4p'),
 ('baile funk', 'spotify:track:6Du0r4fahau45X9bkXIIjB'),
 ('brazilian electronica', 'spotify:track:3LO1I8lQSsXD6gVdU9KZA1')]