Reputation: 10033
I have two lists I want to sort. The first list contains ids and genres strings:
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')
]
and the second list contains genres and other values
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)
]
which I want to sort into a new list, respecting the order of the second list, ending up with:
sorted = [['mpb', u'spotify:track:10KJMfYgg6CORIhtkPn04i'],[...]]
I have tried, to no avail:
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_)
The snippet above fails silently...
What is the best way of achieving my desired result?
Upvotes: 0
Views: 110
Reputation: 53029
You can do an indirect sort on both lists and then use the indices to shuffle one list into the other's order:
>>> 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')]
Upvotes: 0
Reputation: 140168
your data needs reorganizing. First, I'd rebuild a dictionary with ids as key and genres as values (the inverse of your ids_and_genres
list)
Then I'd perform an ordered lookup in that dictionary, using the first item of the first item of genres_and_other_values
(stripped, to remove extra spaces)
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)]
which gives:
[('mpb', 'spotify:track:10KJMfYgg6CORIhtkPn04i'), ('samba', 'spotify:track:59UvKSCJLFDsGOSESlzfAg'), ('forro', 'spotify:track:0ZoJ7jZBHY6SjhbClU7p2B'),...
this method is short and has small complexity: O(n)
(considering that dictionary lookup is O(1)
most of the time)
Upvotes: 2
Reputation: 2711
for list a
and list b
, returning list 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
Upvotes: 0