Advertisement
Guest User

The Pythonista's Legacy

a guest
Jan 20th, 2014
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.01 KB | None | 0 0
  1. -----BEGIN PGP SIGNED MESSAGE-----
  2. Hash: SHA1
  3.  
  4. #!/usr/bin/env python3
  5. #
  6. # So, I've got some free python training for you! This code works both
  7. # with python2 and python3. I love python3's print function, so let's add
  8. # it...
  9.  
  10. from __future__ import print_function
  11.  
  12. # Ok. First thing, did you know about namedtuple? It works as a regular
  13. # tuple, but you can access the fields by name (hence "named" tuple).
  14. # Besides, it is optimized for producing a large amount of instances.
  15.  
  16. from collections import namedtuple
  17.  
  18. # It works as a meta-type: you define types by calling a function.
  19. Row = namedtuple("Row", "name age city")
  20.  
  21. # ...but refer to the documentation (pydoc collections.namedtuple) for
  22. # that. Here a proof of how it works:
  23.  
  24. r = Row("Luke", 40, "Amsterdam")
  25. print("Showing Row:", r)
  26. print("Showing fields of the row:", r.name, r.age, r.city)
  27.  
  28. # Let's take an hypotetical list of results. This Could be the output of
  29. # some stats file, or maybe from a database (even if the database will
  30. # probably have some inner type!).
  31.  
  32. records = [
  33.     Row("Jane", 15, "London"),
  34.     Row("Georg", 15, "Berlin"),
  35.     Row("Urlika", 20, "Stockholm"),
  36.     Row("Johan", 17, "Stockholm"),
  37.     Row("Aldo", 9, "Rome"),
  38.     Row("Hans", 17, "Berlin")
  39.     Row("Petra", 21, "Berlin")
  40. ]
  41.  
  42. # About itertools? It's an extremely nice library of python, with useful
  43. # lazy-evaluated functions [ https://en.wikipedia.org/wiki/Lazy_evaluation ].
  44. # Iterators in general allow to iterate (hence the word) on objects like
  45. # tuples or lists ("iterables").
  46.  
  47. import itertools as it
  48.  
  49. # Iterators are very elegant, and if wisely used they can reduce the
  50. # memory footprint of a program, but on the minus side they get consumed:
  51. # you cannot use the same iterator twice. Example:
  52.  
  53. # I can print lists twice:
  54.  
  55. print('-' * 80)
  56. print("Records")
  57. for r in records:
  58.     print("\t", r)
  59. print("...second shot:")
  60. for r in records:
  61.     print("\t", r)
  62. print("end.")
  63.  
  64. print('-' * 80)
  65.  
  66. # But iterators get consumed
  67. records_iterator = iter(records)
  68. print("Iterated records")
  69. for r in records_iterator:
  70.     print("\t", r)
  71. print("...second shot (will be empty):")
  72. for r in records_iterator:
  73.     print("\t", r)
  74. print("end.")
  75. print('-' * 80)
  76.  
  77. # Also I'll include the "attrgetter" operator. Quoting the documentation:
  78. #
  79. #   After, f=attrgetter('name'), the call f(r) returns r.name.
  80.  
  81. from operator import attrgetter as aget
  82.  
  83. # For example, this is get_city:
  84. get_city = aget('city')
  85.  
  86. # Since the records are namedtuple with a field called `city`,
  87. # `aget('city')` will produce a function returning the `city` field:
  88. r = Row("Luke", 40, "Amsterdam")
  89. print("The city of Luke is:", get_city(r))
  90.  
  91. # Now some interesting use of the groupby function.
  92. #
  93. # It basically works as the "Group By" operator on SQL: group together
  94. # items of a table (in this case an iterator), and allow iteration over
  95. # single groups. The only caveat: items of the same group must be
  96. # contiguous, as for the "uniq" command of unix, which is often preceded
  97. # by the "sort" command, in pipe.
  98. #
  99. # For instance, let's take the `records` list, we defined previously, and
  100. # group the rows by the `city` attribute.  The `get_city` we defined
  101. # before turns out to be a good grouping function So, those items have to
  102. # be sorted by the relevant field...
  103. records_sorted = sorted(records, key=get_city)
  104.  
  105. # ...Then we can use the groupby:
  106. for city, rows in it.groupby(records_sorted, get_city):
  107.     print("City:", city, end="\n\t")
  108.     print(*rows, sep="\n\t", end="\n\n")
  109.  
  110. # Nice thing: this allows us to do some aggregation (e.g. sum, or average)
  111. # quite easily. Want to know the average age by city?
  112. for city, rows in it.groupby(records_sorted, get_city):
  113.     print(
  114.         "City:", city,
  115.         "Avg.age:", sum(map(aget('age'), rows)),
  116.         end="\n\n"
  117.     )
  118.  
  119. # Note: sorted() will return *a list*, not an iterator. That's why we can
  120. # use the it.groupby() function twice on it. If line 99 were
  121. #
  122. #   records_sorted = iter(sorted(records, key=get_city))
  123. #
  124. # Then the second cycle at line 108 would have not worked. Also you may
  125. # try to cycle with it.groupby on records instead of records_sorted: you
  126. # will see the results! :)
  127.  
  128. # Happy hacking.
  129.  
  130. -----BEGIN PGP SIGNATURE-----
  131. Version: GnuPG v1
  132.  
  133. iQIcBAEBAgAGBQJS3aTyAAoJEC+Zq7a6FN+eueYQALImcxP1jJaRrrxtaLqjAZqf
  134. weYjcOq634NuMg2LFdRUV7KFc0GuW6AClGokXSle9F7hGsJZaxaer1VknkN5vmnw
  135. fzzs6soA+FN3fopjTmVxLXJvxrQNP+gSk4iuFF09KNU/E+UZfkKx5vpA+xg1wvr6
  136. R3Bi+jy8mDsz7zHkrv0sDdyIJF9ty6VZe3/afkM3TaaQN7/CRptpkGTJnA9bvkyJ
  137. eA9p5NyRD1eO9e6GScUeJ/Btn9sJ1kzfkYxdsLr4cRFSsRf3X0IymgUNOOpAAyH4
  138. +gvyeUw8iowukJD3B0+YTQgfs7A9LUSZNHd+ElmC+eOJxAgmQwuhsxAvXN0I2seI
  139. +CuNKmf+zF4TGY3bnQHjE2XBk4Q42m7N+gsN1wsd7t4gK/q5jK8Mf8eh8qvXE5tt
  140. H8yLPc6y9kjglFLFzBtrskDKrKZ9M/rRPUJZJJOZ+rrkEAtOPq4JINKfhZL3tOsI
  141. rYPKlBhbl8uEuy6w1lChsEn+yUE+Tct5XL/jF+hkLzlkWLCO9FB15Ta6XHxK+xff
  142. sssbeFOcarFra7ssKK1Hou8LPeoqkUy5AC2ywnp3oOMU3dk6+qXrG0+ROGp5IxXr
  143. 0JiEGiykUmXqdqLAeSAwm8H2Ac7U9+8LT5g1FUTpMsvQezfburyUjmDVWLiaKcNE
  144. z6UCQu37bHVaRM0RmLqX
  145. =+CMW
  146. -----END PGP SIGNATURE-----
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement