Advertisement
Guest User

Untitled

a guest
Sep 28th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.82 KB | None | 0 0
  1. # It is chapter 1 of the book.
  2. import heapq
  3. import json
  4. import os
  5. from operator import itemgetter, attrgetter
  6. from collections import deque, defaultdict, OrderedDict, Counter, namedtuple
  7. from itertools import groupby, compress
  8.  
  9. # Unpacking a Sequence into Separate Variables
  10. """Any sequence (or iterable) can be unpacked into variables using a simple assignment operation."""
  11. x, y = (4, 5)
  12. print(x)
  13. print(y)
  14.  
  15. data = ["ACME", 2, 51.2, (2016, 7, 2)]
  16. name, shares, price, date = data
  17. print(name, shares, price)
  18. print(date)
  19.  
  20. names, shares, price, (year, month, day) = data
  21. print(name, shares, price)
  22. print(year)
  23. print(month)
  24. print(day)
  25.  
  26. names, shares, _, (year, month, _) = data
  27. print(names, shares, year, month)
  28.  
  29. """"Unpacking actually works with any object that happens to be iterable, not just tuples or lists.
  30. This includes strings, files, iterators, and generators"""
  31.  
  32. s = "hello"
  33. a, b, c, multi_dict3, e = s
  34. print(a, c, e)
  35.  
  36.  
  37. # Unpacking Elements from Iterables of Arbitrary Length
  38. def drop_fist_last(grades):
  39. first, *middle, last = grades
  40. return sum(middle) / len(middle)
  41.  
  42.  
  43. drop_fist_last([1, 2, 3, 4, 5, 6, 7, 8])
  44.  
  45. record = ["Dave", "Dave@exa,ple.com", "721-423-2341", "871-562-3427"]
  46. name, email, *phone_numbers = record
  47.  
  48. """It’s worth noting that the phone_numbers variable will always be a list, regardless of how many phone numbers are unpacked."""
  49. print(phone_numbers)
  50.  
  51. *trailing, current = [1, 2, 3, 4, 5, 6, 7, 8]
  52. print(trailing)
  53. print(current)
  54.  
  55. """It is worth noting that the star syntax can be especially useful when iterating over a sequence of tuples of varying length"""
  56. record = [("foo", 2, 3), ("bar", "hello"), ("foo", 4, 7)]
  57.  
  58.  
  59. def do_foo(x_do, y_do):
  60. print("foo", x_do, y_do)
  61.  
  62.  
  63. def do_bar(s_do):
  64. print("bar", s_do)
  65.  
  66.  
  67. for tag, *args in record:
  68. if tag == "foo":
  69. do_foo(*args)
  70. elif tag == "bar":
  71. do_bar(*args)
  72.  
  73. line_read = "nobody:*:2:2:Unprivileged User:var/empty:/ermia/home/bin"
  74. username, *fields, home_dir, sh = line_read.split(":")
  75. print(username, home_dir, sh)
  76.  
  77. data = ["ACME", 2, 51.2, (2016, 7, 2)]
  78. journal_name, *ign1, (year, *ign2) = data
  79. print(journal_name, year)
  80.  
  81. """writing functions that perform such splitting in order to carry out some kind of clever recursive algorithm"""
  82.  
  83.  
  84. def sum1(items):
  85. head, *tail = items
  86. return head + sum1(tail) if tail else head
  87.  
  88.  
  89. sum1([1, 2, 3, 4, 5])
  90.  
  91. # Keeping the Last N Items
  92. """Using deque(maxlen=N) creates a fixed-sized queue.
  93. When new items are added and the queue is full, the oldest item is automatically removed."""
  94.  
  95.  
  96. def search(lines, pattern, history=5):
  97. previous_lines = deque(maxlen=history)
  98. for line_to_read in lines:
  99. if pattern in line_to_read:
  100. yield line_to_read, previous_lines
  101. previous_lines.append(line_to_read)
  102.  
  103.  
  104. with open("foo.txt") as file:
  105. for line, previous_line in search(file, "python", 5):
  106. for p_line in previous_line:
  107. print(p_line, end=" ")
  108. print("_" * 20)
  109.  
  110. q = deque(maxlen=3)
  111. q.append(1)
  112. q.append(2)
  113. q.append(3)
  114. print(q)
  115.  
  116. q.append(4)
  117. print(q)
  118.  
  119. # Finding the Largest or Smallest N Items
  120. """The heapq module has two functions—nlargest() and nsmallest()"""
  121. nums = [12, 15, 3, 56, 43, 23, 87, 99, 57]
  122. print(heapq.nlargest(5, nums))
  123. print(heapq.nsmallest(6, nums))
  124.  
  125. """Both functions also accept a key parameter that allows them to be used with more complicated data structures."""
  126. portfolio = [{'item_name': 'IBM', 'shares': 100, 'price': 91.1},
  127. {'item_name': 'APPLE', 'shares': 50, 'price': 543.22},
  128. {'item_name': 'FB', 'shares': 200, 'price': 21.09},
  129. {'item_name': 'HPQ', 'shares': 35, 'price': 31.75},
  130. {'item_name': 'YAHOO', 'shares': 45, 'price': 16.35},
  131. {'item_name': 'ACME', 'shares': 75, 'price': 115.65}
  132. ]
  133. print(heapq.nsmallest(2, portfolio, key=lambda structure: structure["price"]))
  134. print(heapq.nlargest(3, portfolio, key=lambda structure: structure["price"]))
  135.  
  136. # Mapping Keys to Multiple Values in a Dictionary
  137. """If you want to map keys to multiple values, you need to store the multiple values in another container such as a list or set."""
  138. multi_dict1 = {"a": [1, 2, 3],
  139. "b": [4, 5]}
  140. multi_dict2 = {"a": {1, 2, 3},
  141. "b": {4, 5}}
  142. """ Use a set if you want to eliminate duplicates (and don’t care about the order)."""
  143.  
  144. """To easily construct such dictionaries, you can use defaultdict in the collections module."""
  145. multi_dict3 = defaultdict(list)
  146. multi_dict3["a"].append(1)
  147. multi_dict3["b"].append(2)
  148. multi_dict3["a"].append(3)
  149. multi_dict3["b"].append(4)
  150. multi_dict3["b"].append(5)
  151. print(multi_dict3)
  152.  
  153. # Keeping Dictionaries in Order
  154. """To control the order of items in a dictionary, you can use an OrderedDict from the collections module."""
  155. ordered_dict = OrderedDict()
  156. ordered_dict[1] = "foo"
  157. ordered_dict[2] = "bar"
  158. ordered_dict[3] = "spam"
  159.  
  160. for key in ordered_dict:
  161. print(key, ordered_dict[key])
  162.  
  163. """"If you want to precisely control the order of fields appearing in a JSON encoding,
  164. first building the data in an OrderedDict will do the trick:"""
  165. print(json.dumps(ordered_dict))
  166.  
  167. # Calculating with Dictionaries
  168. prices = {"ACME": 45.23,
  169. "APPLE": 46.25,
  170. "YAHOO": 27.79,
  171. "GOOGLE": 54.23}
  172.  
  173. print(max(zip(prices.values(), prices.keys())))
  174. print(min(zip(prices.values(), prices.keys())))
  175. print(sorted(zip(prices.values(), prices.keys())))
  176.  
  177. # Finding Commonalities in Two Dictionaries
  178. dict1 = {"x": 1, "y": 2, "z": 3}
  179. dict2 = {"w": 11, "x": 4, "y": 2}
  180. dict1.keys() & dict2.keys()
  181. dict1.keys() - dict2.keys()
  182. dict1.items() & dict2.items()
  183.  
  184. dict3 = {key: dict1[key] for key in dict1.keys() - {'z', 'w'}}
  185. print(dict3)
  186.  
  187. # Naming a Slice
  188. """In general, the built-in slice() creates a slice object that can be used anywhere a slice is allowed."""
  189.  
  190. item = [0, 1, 2, 3, 4, 5, 6]
  191. a = slice(2, 4)
  192.  
  193. print(item[2:4])
  194. print(item[a])
  195.  
  196. item[a] = [10, 11]
  197. print(item)
  198.  
  199. del item[a]
  200. print(item)
  201.  
  202. # Determining the Most Frequently Occurring Items in a Sequence
  203. words = [
  204. 'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
  205. 'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
  206. 'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
  207. 'my', 'eyes', "you're", 'under']
  208.  
  209. words_count = Counter(words)
  210. top_three = words_count.most_common(3)
  211. print(top_three)
  212.  
  213. """As input, Counter objects can be fed any sequence of hashable input items."""
  214. print(words_count['not'])
  215. print(words_count["eyes"])
  216.  
  217. """If you want to increment the count manually, simply use addition:"""
  218. more_words = ['why', 'are', 'you', 'not', 'looking', 'in', 'my', 'eyes']
  219. for word in more_words:
  220. words_count[word] += 1
  221.  
  222. print(words_count["eyes"])
  223.  
  224. """Or, alternatively, you could use the update() method:"""
  225. words_count.update(more_words)
  226. print(words_count['eyes'])
  227.  
  228. """A little-known feature of Counter instances is that they can be easily combined using various mathematical operations."""
  229. words_count = Counter(words)
  230. print(words_count)
  231.  
  232. words_count_more = Counter(more_words)
  233. print(words_count_more)
  234.  
  235. print(words_count + words_count_more)
  236. print(words_count - words_count_more)
  237.  
  238. # Sorting a List of Dictionaries by a Common Key
  239. rows = [
  240. {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
  241. {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
  242. {'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
  243. {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}]
  244.  
  245. rows_by_name = sorted(rows, key=itemgetter("fname"))
  246. print(rows_by_name)
  247.  
  248. rows_by_id = sorted(rows, key=itemgetter("uid"))
  249. print(rows_by_id)
  250.  
  251. """The itemgetter() function can also accept multiple keys."""
  252. rows_by_name_and_id = sorted(rows, key=itemgetter("fname", "lname"))
  253. print(rows_by_name_and_id)
  254.  
  255. """The functionality of itemgetter() is sometimes replaced by lambda expressions."""
  256. rows_by_name = sorted(rows, key=lambda r: r["fname"])
  257. print(rows_by_name)
  258.  
  259. """Last, but not least, don’t forget that the technique shown in this recipe can be applied to functions such as min() and max()."""
  260. min_rows_by_uid = min(rows, key=lambda r: r["uid"])
  261. print(min_rows_by_uid)
  262.  
  263.  
  264. # Sorting Objects Without Native Comparison Support
  265. class User:
  266. def __init__(self, user_id):
  267. self.user_id = user_id
  268.  
  269. def __repr__(self):
  270. return "User({})".format(self.user_id)
  271.  
  272.  
  273. users = [User(24), User(45), User(32)]
  274. print(sorted(users, key=lambda u: u.user_id))
  275.  
  276. """Instead of using lambda, an alternative approach is to use operator.attrgetter():"""
  277. print(sorted(users, key=attrgetter("user_id")))
  278.  
  279. """It is also worth noting that the technique used in this recipe can be applied to functions such as min() and max()."""
  280. max(users, key=attrgetter("user_id"))
  281.  
  282. # Grouping Records Together Based on a Field
  283. """The itertools.groupby() function is particularly useful for grouping data together like this."""
  284. rows = [
  285. {'address': '5412 N CLARK', 'date': '07/01/2012'},
  286. {'address': '5148 N CLARK', 'date': '07/04/2012'},
  287. {'address': '5800 E 58TH', 'date': '07/02/2012'},
  288. {'address': '2122 N CLARK', 'date': '07/03/2012'},
  289. {'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
  290. {'address': '1060 W ADDISON', 'date': '07/02/2012'},
  291. {'address': '4801 N BROADWAY', 'date': '07/01/2012'},
  292. {'address': '1039 W GRANVILLE', 'date': '07/04/2012'}, ]
  293.  
  294. """If you want to iterate over the data in chunks grouped by date,
  295. first sort by the desired field (in this case, date) and then use itertools.groupby():"""
  296.  
  297. # sort by the desired field first
  298. rows.sort(key=itemgetter("date"))
  299.  
  300. # iterate over the groups
  301. for date, items in groupby(rows, key=itemgetter("date")):
  302. print(date)
  303. for i in items:
  304. print(" ", i)
  305.  
  306. # Filtering Sequence Elements
  307. """The easiest way to filter sequence data is often to use a list comprehension."""
  308. my_list = [-4, -5, 0, 3, -2, 17, -43, 23]
  309. my_list_positive = [n for n in my_list if n > 0]
  310. my_list_clip = [n if n > 0 else 0 for n in my_list]
  311.  
  312. print(my_list_positive)
  313. print(my_list_clip)
  314.  
  315. """you can also use generator expressions to produce the filtered values iteratively."""
  316. my_list_positive = (n for n in my_list if n > 0)
  317. for item in my_list_positive:
  318. print(item)
  319.  
  320. """In more complicated cases, put the filtering code into its own function and use the built-in filter() function."""
  321.  
  322.  
  323. def is_int(value):
  324. try:
  325. int(value)
  326. return True
  327. except ValueError:
  328. return False
  329.  
  330.  
  331. """filter() creates an iterator, so if you want to create a list of results, make sure you also use list() as shown."""
  332.  
  333. int_values = list(filter(is_int, ["1", "2", "NA", "4", "-"]))
  334. print(int_values)
  335.  
  336. """Another filtering tool is itertools.compress(), which takes an iterable and an accompanying Boolean selector sequence as input."""
  337. addresses = [
  338. '5412 N CLARK',
  339. '5148 N CLARK',
  340. '5800 E 58TH',
  341. '2122 N CLARK'
  342. '5645 N RAVENSWOOD',
  343. '1060 W ADDISON',
  344. '4801 N BROADWAY',
  345. '1039 W GRANVILLE',
  346. ]
  347.  
  348. counts = [0, 3, 10, 4, 1, 7, 6, 1]
  349. more_five = [n > 5 for n in counts]
  350. print(more_five)
  351. list(compress(addresses, more_five))
  352.  
  353. # Extracting a Subset of a Dictionary
  354. """This is easily accomplished using a dictionary comprehension."""
  355.  
  356. prices = {"APPLE": 42.5, "GOOGLE": 54.2, "YAHOO": 48.73}
  357. prices1 = {key: value for key, value in prices.items() if value > 45}
  358. # or prices1 = dict((key,value) for key, value in prices.items() if value > 45}
  359. print(prices1)
  360.  
  361. tech_names = {"APPLE", "FACEBOOK", "GOOGLE"}
  362. prices2 = {key: value for key, value in prices.items() if key in tech_names}
  363. print(prices2)
  364.  
  365. # Mapping Names to Sequence Elements
  366. """collections.namedtuple() provides these benefits, while adding minimal overhead over using a normal tuple object."""
  367.  
  368. subscriber = namedtuple("subscriber", ["address", "joined"])
  369. sub = subscriber("jon@example.edu", "2010-7-18")
  370. print(sub)
  371. print(sub.address, sub.joined)
  372.  
  373. """namedtuple is interchangeable with a tuple and supports all of the usual tuple operations such as indexing and unpacking. For example:"""
  374. len(sub)
  375. address1, joined1 = sub
  376. print(address1, joined1)
  377.  
  378. # Transforming and Reducing Data at the Same Time
  379. """A very elegant way to combine a data reduction and a transformation is to use a generator-expression argument."""
  380. nums = [1, 2, 3, 4, 5]
  381. print(sum(x ** 2 for x in nums))
  382.  
  383. # Determine if any .py files exist in a directory
  384. files = os.listdir("/home/ermia/PycharmProjects/Python Cookbook")
  385. if any(name.endswith(".py") for name in files):
  386. print("there is a python file")
  387. else:
  388. print("there is no python file")
  389.  
  390. # Output a tuple as CSV
  391. s = ("ACME", 542.654, 72.3)
  392. print(",".join(str(x) for x in s))
  393.  
  394. # # Data reduction across fields of a data structure
  395. portfolio = [
  396. {'item_name': 'GOOGLE', 'shares': 50},
  397. {'item_name': 'YaHOO', 'shares': 75},
  398. {'item_name': 'AOL', 'shares': 20},
  399. {'item_name': 'FACEBOOK', 'shares': 65}
  400. ]
  401. min_shares = min(s["shares"] for s in portfolio)
  402. print(min_shares)
  403.  
  404. """Certain reduction functions such as min() and max() accept a key argument,
  405. which might be useful in situations where you might be inclined to use a generator"""
  406.  
  407. min_shares = min(portfolio, key=lambda item_name: item_name["shares"])
  408. print(min_shares)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement