proffreda

Python Data Abstractions

Sep 18th, 2016
317
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.95 KB | None | 0 0
  1. Python Data Abstractions
  2.  
  3. Collection - An Object identifying a group of elements, which may be ordered and unordered.
  4. Iterable - An ordered collection used often in for loops, capable of returning one element at time.
  5. Sequence - An iterable, ordered collection, with fast access to next elements.
  6.  
  7. Collections are either:
  8. Mutable (identities changeable in place)
  9. Immutable (identities unchangeable)
  10.  
  11.  
  12. Builtin Examples:
  13. Lists (sequence, ordered, iterable, mutable)
  14. Tuples (sequence, ordered, iterable, immutable)
  15. Dictionaries (non-sequence, unordered, iterable, mutable)
  16. Strings (sequence, ordered, iterable, immutable)
  17.  
  18.  
  19. Dictionaries
  20. • Unordered, Iterable, Mutable Collection
  21. • Keys in dictionaries and elements in sets:
  22. • Keys can’t be mutable values, such as lists and dictionaries - they mush be 'hashable' like strings.
  23. • Must be unique, i.e., no duplicates
  24. • If you want to associate multiple values with a key, store them all in a sequence (list) value, e.g.:
  25. parity = {'odds': [1, 3, 5], 'evens': [2, 4, 6]}
  26.  
  27. Dictionary as a collection of counters
  28. Dictionaries are used as lookup tables since the efficiently map keys to values. A popular use is when keys are mapped to counter values. We call such a dictionary a 'histogram'.
  29. Here is what the code might look like to create a histogrm, when given an iterable collection s:
  30.  
  31. def histogram(s):
  32. d = dict()
  33. for c in s:
  34. if c not in d:
  35. d[c] = 1
  36. else:
  37. d[c] += 1
  38. return d
  39.  
  40. Here’s how it works:
  41.  
  42. >>> h = histogram('brontosaurus')
  43. >>> h
  44. {'a': 1, 'b': 1, 'o': 2, 'n': 1, 's': 2, 'r': 2, 'u': 2, 't': 1}
  45.  
  46.  
  47. The Changing Identity of Data
  48. Programs often exhibit brittleness when data models change over time. Programmers need to carefully consider whether and how a data model is affected over time. Consider Suits in Playing Cards: Playing cards were invented in China, perhaps around the 9th century, and have evolved over time. An early deck had three suits, which corresponded to denominations of money.
  49.  
  50. >>> chinese = ['coin', 'string', 'myriad'] # A list literal
  51. >>> suits = chinese # Two names refer to the same list
  52.  
  53. As cards migrated to Europe (perhaps through Egypt), only the suit of coins remained in Spanish decks (oro).
  54.  
  55. >>> suits.pop() # Remove and return the final element
  56. 'myriad'
  57. >>> suits.remove('string') # Remove the first element that equals the argument
  58.  
  59. Three more suits were added (they evolved in name and design over time),
  60.  
  61. >>> suits.append('cup') # Add an element to the end
  62. >>> suits.extend(['sword', 'club']) # Add all elements of a sequence to the end
  63. and Italians called swords spades.
  64.  
  65. >>> suits[2] = 'spade' # Replace an element
  66. giving the suits of a traditional Italian deck of cards.
  67.  
  68. >>> suits
  69. ['coin', 'cup', 'spade', 'club']
  70.  
  71. The French variant used today in the U.S. changes the first two suits:
  72.  
  73. >>> suits[0:2] = ['heart', 'diamond'] # Replace a slice
  74. >>> suits
  75. ['heart', 'diamond', 'spade', 'club']
  76. Methods also exist for inserting, sorting, and reversing lists. All of these mutation operations change the value of the list; they do not create new list objects.
  77.  
  78. Sharing and Identity. Because we have been changing a single list rather than creating new lists, the object bound to the name chinese has also changed, because it is the same list object that was bound to suits!
  79.  
  80. >>> chinese # This name co-refers with "suits" to the same changing list
  81. ['heart', 'diamond', 'spade', 'club']
  82. This behavior is new. Previously, if a name did not appear in a statement, then its value would not be affected by that statement. With mutable data, methods called on one name can affect another name at the same time.
  83.  
  84. Lists can be copied using the list constructor function. Changes to one list do not affect another, unless they share structure.
  85.  
  86. >>> nest = list(suits) # Bind "nest" to a second list with the same elements
  87. >>> nest[0] = suits # Create a nested list
  88. According to this environment, changing the list referenced by suits will affect the nested list that is the first element of nest, but not the other elements.
  89.  
  90. >>> suits.insert(2, 'Joker') # Insert an element at index 2, shifting the rest
  91. >>> nest
  92. [['heart', 'diamond', 'Joker', 'spade', 'club'], 'diamond', 'spade', 'club']
  93. And likewise, undoing this change in the first element of nest will change suit as well.
  94.  
  95. >>> nest[0].pop(2)
  96. 'Joker'
  97. >>> suits
  98. ['heart', 'diamond', 'spade', 'club']
  99.  
  100. Mutation through Function Calls
  101. A function can change the value of any object in its scope
  102. A function’s scope also includes parent frames
  103. >>> four = [1, 2, 3, 4]
  104. >>> len(four)
  105. 4
  106. >>> mystery(four)
  107. >>> len(four)
  108. 2
  109.  
  110. def mystery(s):
  111. s.pop()
  112. s.pop()
  113. #OR
  114. def mystery(s):
  115. s[2:] = []
  116.  
  117. >>> four = [1, 2, 3, 4]
  118. >>> len(four)
  119. 4
  120. >>> another_mystery() # No arguments!
  121. >>> len(four)
  122. 2
  123.  
  124. def another_mystery():
  125. four.pop()
  126. four.pop()
  127.  
  128. Identity vs Equality
  129. • Because mutable values can change, the notion of equality is not as strong anymore
  130. • Two immutable values are always equal or always unequal to each other
  131. • Two mutable values can be sometimes equal and sometimes unequal to each other
  132. • Each value also has an identity, which cannot change
  133. • A list still has the same identity even if we change its contents
  134. • Conversely, two lists, even if they contain the same
  135. elements, never have the same identity
  136.  
  137. Identity vs Equality
  138. Identity
  139. <exp0> is <exp1>
  140. evaluates to True if both <exp0> and <exp1> evaluate to the same object
  141.  
  142. Equality
  143. <exp0> == <exp1>
  144. evaluates to True if both <exp0> and <exp1> evaluate to equal values
  145. Identical objects are always equal values
  146.  
  147.  
  148. >>> def f(s=[]):
  149. ... s.append(3)
  150. ... return len(s)
  151. ...
  152. >>> f()
  153. 1
  154. >>> f()
  155. 2
  156. >>> f()
  157. 3
  158.  
  159. Summary
  160. • Mutable values such as lists and dictionaries have state and can be changed
  161. • This can be useful in writing programs that are more efficient and more understandable
  162. • Immutable values cannot be changed after they are created
  163. • This is simpler and safer: immutable values that are equal (or unequal) will always be equal (or unequal)
  164. • Knowing when and where to use both types of values is an important part of being a good programmer!
  165.  
  166. Quiz Question 1
  167.  
  168. Define if_this_not_that, which takes a list of integers i_list, and an integer this, and for each element in i_list if the element is larger than this then print the element, otherwise print that.
  169.  
  170. def if_this_not_that(i_list, this):
  171. """
  172. >>> original_list = [1, 2, 3, 4, 5]
  173. >>> if_this_not_that(original_list, 3)
  174. that
  175. that
  176. that
  177. 4
  178. 5
  179. """
  180.  
  181. Quiz Question 2: Replace All
  182.  
  183. Given a dictionary d, replace all occurrences of x as a value (not a key) with y.
  184.  
  185. def replace_all(d, x, y):
  186. """
  187. >>> d = {'foo': 2, 'bar': 3, 'garply': 3, 'xyzzy': 99}
  188. >>> replace_all(d, 3, 'poof')
  189.  
  190. >>> d == {'foo': 2, 'bar': 'poof', 'garply': 'poof', 'xyzzy': 99}
  191. True
  192. """
Add Comment
Please, Sign In to add comment