0

I am searching for pythonic way of getting first N element from a DefaultDict. I searched for it in few forums. Couldn't find any useful solution. I tried the following but this doesn't stop the execution as expected.

Code:

d_2 = defaultdict(list)
i = -1

for x,y in sorted(d_2.items(), reverse = True):
            i = i + 1
            if i <= 20:
                print ("%d, %s" %(i,x))
                most_used_val_bar.add(str(x),y)
            else:
                break
most_used_val_bar.render_to_file(directory + "/most_used_values.svg")

But this code doesn't break when i goes over 20, I am using this for loop to plot using Pygal Plotting Library

v.padmanabhan
  • 37
  • 2
  • 5
  • 6
    There is no such thing as "first N elements" in a `defaultdict`, because, as with a plain `dict`, the elements are in arbitrary order. – abarnert Apr 16 '15 at 10:46
  • Also, your `d_2` here is empty, so it doesn't have _any_ elements. – abarnert Apr 16 '15 at 10:47

2 Answers2

3

If you're actually looking for the first 20 items in a defaultdict, that's meaningless; the items in a defaultdict, as with a normal dict, are in arbitrary order, so there are no "firsts".

But from your code, I suspect you may be looking for the first 20 items in the iterator you got from sorting the dict's items. In that case, the answer is easy. It doesn't matter that the values originally came from a defaultdict; you've got an iterable, you want to slice it to the first 20 items, you call islice:

for x, y in itertools.islice(sorted(d_2.items(), reverse=True), 20):

That being said, it may be clearer (and will be more space-efficient) to just build a list of the top 20 in the first place, instead of building a sorted list and then taking the top 20:

for x, y in heapq.nsmallest(20, d_2.items()):
abarnert
  • 354,177
  • 51
  • 601
  • 671
1

Iterate over a slice of the first 20 elements of your sorted dictionary item list:

for x,y in sorted(d_2.items(), reverse = True)[:20]:
Craig Burgler
  • 1,749
  • 10
  • 19