3

In python2.7, the following code takes the dictionary fd (in this example representing a frequency distribution of words and their counts), and separates it into a list of two lists: [[the keys],[values]]:

sortedDKandVs = [zip(*sorted(fd.items(), key=itemgetter(1), reverse=True))] #[word,word,...],[count,count]

I can then do, for example:

keys = sortedDKandVs[0]
values = sortedDKandVs[1]

This no longer works in Python3 and I want to know how to transform the code.

None of the answers here How to unzip a list of tuples into individual lists? work anymore because in Python3 zip objects return iterators instead of lists, but I am not sure how to transform the answers.

Community
  • 1
  • 1
Tommy
  • 11,318
  • 11
  • 58
  • 94

1 Answers1

9

Python 2:

Python 2.7.6 (default, Apr  9 2014, 11:48:52) 
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> di={'word1':22, 'word2':45, 'word3':66}
>>> zip(*sorted(di.items(), key=itemgetter(1), reverse=True))
[('word3', 'word2', 'word1'), (66, 45, 22)]
>>> k,v=zip(*sorted(di.items(), key=itemgetter(1), reverse=True))
>>> k
('word3', 'word2', 'word1')
>>> v
(66, 45, 22)

Python 3:

Python 3.4.1 (default, May 19 2014, 13:10:29) 
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> di={'word1':22, 'word2':45, 'word3':66}
>>> k,v=zip(*sorted(di.items(), key=itemgetter(1), reverse=True))
>>> k
('word3', 'word2', 'word1')
>>> v
(66, 45, 22)

It is exactly the same for both Python 2 and Python 3

If you want lists vs tuples (both Python 3 and Python 2):

>>> k,v=map(list, zip(*sorted(di.items(), key=itemgetter(1), reverse=True)))
>>> k
['word3', 'word2', 'word1']
>>> v
[66, 45, 22]
dawg
  • 90,796
  • 20
  • 120
  • 197
  • The way you have posted also works; meaning, the second example in mine also works in Python2. However, the python2 code I gave in mine does not work in Python3. – Tommy Jul 06 '14 at 03:09
  • 1
    The way you posted yours is just an error. You are taking the result of a function and arbitrarily putting in a list with `[]` – dawg Jul 06 '14 at 04:23
  • But why do it if you can do what you want and it works on both versions? Just correct the way your code is. – dawg Jul 06 '14 at 04:53
  • @Tommy: May 'error' is too harsh, but it is an unnecessary version dependency and not at all necessary -- ever -- to do what you are doing on Python 2. – dawg Jul 07 '14 at 04:08
  • `itemgetter` is undefined in my *Python 3.5.1 (default, Dec 29 2015, 16:40:59); [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin*. I had to replace that with `lambda x: x[1]` – Demis Jan 03 '16 at 00:18
  • If I understand correctly, the `[]`'s around the `zip()` are to convert to list, which would also be achieved by `list( zip(...) )`, which should also work in both versions (while maintaining original functionality). – Demis Jan 03 '16 at 00:39
  • 1
    You need `from operator import itemgetter` to use [itemgetter](https://docs.python.org/2/library/operator.html#operator.itemgetter) – dawg Jan 04 '16 at 02:00
  • @Tommy Wrapping the `zip` in square brackets will not convert it to a list, but instead create a list with one item. This is true for both Python 2 and Python 3, so the code in the question does not work for either version. The reason the code in the question will not work in Python 3 even if you fix that error is because you can't get `sortedDKandVs[0]` and `sortedDKandVs[1]` when `sortedDKandVs` is a `zip` object. But unpacking `keys, values = sortedDKandVs` works both in Python 2 and Python 3, and is the preferred way to do it. – nog642 Oct 21 '19 at 00:51