29

What I came up with is:

keys, values = zip(*[(key, value) for (key, value) in my_dict.iteritems()])

But I am not satisfied. What do the pythonistas say?

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
Aufwind
  • 25,310
  • 38
  • 109
  • 154
  • 4
    BTW notice that your list comprehension should ring alarm bells because it doesn't do anything -- no `if` clause to filter and no function being mapped either. – Katriel Jul 07 '11 at 16:03

2 Answers2

82
keys, values = zip(*d.items())
FogleBird
  • 74,300
  • 25
  • 125
  • 131
44

What about using my_dict.keys() and my_dict.values()?

keys, values = my_dict.keys(), my_dict.values()
serv-inc
  • 35,772
  • 9
  • 166
  • 188
Constantinius
  • 34,183
  • 8
  • 77
  • 85
  • 1
    You mean: `keys, values = dict.keys(), dict.values()`? – Aufwind Jul 07 '11 at 15:09
  • 16
    This works because one of the contracts with `dict` is that the order of keys and values within the dict will correspond as long as the size of the dict does not change. – Ignacio Vazquez-Abrams Jul 07 '11 at 15:12
  • @Constantinius: This is really elegant, thanks! @Ignacio: Thanks a lot! This was the enlightening I hoped for and destroys my concernes about the consistency of both lists, by what I meant ordering. – Aufwind Jul 07 '11 at 15:19
  • 9
    Warning: I'm pretty sure this isn't threadsafe (if that matters to you). Because dict.keys() is called separately from dict.values(), there's an opportunity for a race condition where the dict is modified between those calls. Unpacking dict.items() is safer here because it's a single function call and can't possibly return a different number of keys and values. – Kirk Strauser Jul 07 '11 at 16:06
  • @Kirk, thank you. That is indeed good to know! I was only interested in preserving order, but I'll keep your advice in mind. – Aufwind Jul 07 '11 at 16:19
  • @Aufwind, according to [this comment](http://stackoverflow.com/questions/6612769/is-there-a-more-elegant-way-for-unpacking-keys-and-values-of-a-dictionary-into-t#comment7805058_6612795), if the dict is modified between the calls to keys() and values() the order will *not* be preserved. I think [the other answer](http://stackoverflow.com/a/6612821/5419599) is better than this one. – Wildcard Sep 02 '16 at 22:50
  • 2
    Beware: dict.keys() and dict.values() won't return a list. You'll have to typecast it to list or set. Like list(dict.keys()) – Rohit Taneja Aug 15 '17 at 10:07
  • 2
    @RohitTaneja: In Python 3 yes, in Python 2 (which I had in mind when writing this answer) both return lists. – Constantinius Aug 15 '17 at 21:27
  • This doesn't solve the problem. You do not end up with two lists, you have to cast to a list for this to answer the OPs original request – Will.Evo Oct 12 '21 at 20:05
  • @Will.Evo At the time this answer was given, Python 3 was not yet released. And in Python 2, `.keys()` and `.values()` actually returned lists. But yeah, nowadays you have to convert these objects to lists first. – Constantinius Oct 21 '21 at 18:54