|
21 | 21 | "cell_type": "markdown",
|
22 | 22 | "metadata": {},
|
23 | 23 | "source": [
|
24 |
| - "Let's quickly see how to do this again, using a string as the underlying iterable:" |
| 24 | + "Let's quickly see how do this again, using a string as the underlying iterable:" |
25 | 25 | ]
|
26 | 26 | },
|
27 | 27 | {
|
|
91 | 91 | "cell_type": "markdown",
|
92 | 92 | "metadata": {},
|
93 | 93 | "source": [
|
94 |
| - "A fairly typical use case for this would be when reading data from a CSV file where you know the first few lines consist of information about the data rather than just the data itself.\n", |
| 94 | + "A fairly typical use case for this would be when reading data from a CSV file where you know the first few lines consist of information abotu teh data rather than just the data itself.\n", |
95 | 95 | "\n",
|
96 | 96 | "Let's try this using a CSV file I have saved alongside the Jupyter notebook."
|
97 | 97 | ]
|
|
953 | 953 | "Here's what we want to do: \n",
|
954 | 954 | "* read the first line to get the column headers and create a named tuple class\n",
|
955 | 955 | "* read data types from second line and store this so we can cast the strings we are reading to the correct data type\n",
|
956 |
| - "* read the data rows and parse them into named tuples" |
| 956 | + "* read the data rows and parse them into a named tuples" |
957 | 957 | ]
|
958 | 958 | },
|
959 | 959 | {
|
|
1735 | 1735 | "with open('cars.csv') as file:\n",
|
1736 | 1736 | " file_iter = iter(file)\n",
|
1737 | 1737 | " headers = next(file_iter).strip('\\n').split(';')\n",
|
1738 |
| - " Car = namedtuple('Car', headers)\n", |
1739 | 1738 | " data_types = next(file_iter).strip('\\n').split(';')\n",
|
1740 | 1739 | " cars_data = [cast_row(data_types, \n",
|
1741 | 1740 | " line.strip('\\n').split(';'))\n",
|
|
1803 | 1802 | "with open('cars.csv') as file:\n",
|
1804 | 1803 | " file_iter = iter(file)\n",
|
1805 | 1804 | " headers = next(file_iter).strip('\\n').split(';')\n",
|
1806 |
| - " Car = namedtuple('Car', headers)\n", |
1807 | 1805 | " data_types = next(file_iter).strip('\\n').split(';')\n",
|
1808 | 1806 | " cars = [Car(*cast_row(data_types, \n",
|
1809 | 1807 | " line.strip('\\n').split(';')))\n",
|
|
1829 | 1827 | "source": [
|
1830 | 1828 | "cars[0]"
|
1831 | 1829 | ]
|
1832 |
| - }, |
1833 |
| - { |
1834 |
| - "cell_type": "markdown", |
1835 |
| - "metadata": {}, |
1836 |
| - "source": [ |
1837 |
| - "#### Example 2" |
1838 |
| - ] |
1839 |
| - }, |
1840 |
| - { |
1841 |
| - "cell_type": "markdown", |
1842 |
| - "metadata": {}, |
1843 |
| - "source": [ |
1844 |
| - "Here's another example - suppose we have a loop that iterates over some range of integers. As we loop through those integers we want to create a tuple containing the integer and a string that cycles over a finite set (smaller than the list of integers).\n", |
1845 |
| - "\n", |
1846 |
| - "```\n", |
1847 |
| - "1, 2, 3, 4, 5, 6, 7, 8, 9, ...\n", |
1848 |
| - "\n", |
1849 |
| - "N, S, W, E\n", |
1850 |
| - "```\n", |
1851 |
| - "\n", |
1852 |
| - "and we want to generate\n", |
1853 |
| - "\n", |
1854 |
| - "```\n", |
1855 |
| - "1N, 2S, 3W, 4E, 5N, 6S, 7W, 8E, 9N, ...\n", |
1856 |
| - "```\n" |
1857 |
| - ] |
1858 |
| - }, |
1859 |
| - { |
1860 |
| - "cell_type": "markdown", |
1861 |
| - "metadata": {}, |
1862 |
| - "source": [ |
1863 |
| - "We could do it this way by creating a custom iterator for the list `['N', 'S', 'W', 'E']` that will cycle over that list indefinitely:" |
1864 |
| - ] |
1865 |
| - }, |
1866 |
| - { |
1867 |
| - "cell_type": "code", |
1868 |
| - "execution_count": 23, |
1869 |
| - "metadata": { |
1870 |
| - "collapsed": true |
1871 |
| - }, |
1872 |
| - "outputs": [], |
1873 |
| - "source": [ |
1874 |
| - "class CyclicIterator:\n", |
1875 |
| - " def __init__(self, lst):\n", |
1876 |
| - " self.lst = lst\n", |
1877 |
| - " self.i = 0\n", |
1878 |
| - " \n", |
1879 |
| - " def __iter__(self):\n", |
1880 |
| - " return self\n", |
1881 |
| - " \n", |
1882 |
| - " def __next__(self):\n", |
1883 |
| - " result = self.lst[self.i % len(self.lst)]\n", |
1884 |
| - " self.i += 1\n", |
1885 |
| - " return result" |
1886 |
| - ] |
1887 |
| - }, |
1888 |
| - { |
1889 |
| - "cell_type": "code", |
1890 |
| - "execution_count": 24, |
1891 |
| - "metadata": { |
1892 |
| - "collapsed": true |
1893 |
| - }, |
1894 |
| - "outputs": [], |
1895 |
| - "source": [ |
1896 |
| - "iter_cycl = CyclicIterator('NSWE')" |
1897 |
| - ] |
1898 |
| - }, |
1899 |
| - { |
1900 |
| - "cell_type": "code", |
1901 |
| - "execution_count": 25, |
1902 |
| - "metadata": {}, |
1903 |
| - "outputs": [ |
1904 |
| - { |
1905 |
| - "name": "stdout", |
1906 |
| - "output_type": "stream", |
1907 |
| - "text": [ |
1908 |
| - "N\n", |
1909 |
| - "S\n", |
1910 |
| - "W\n", |
1911 |
| - "E\n", |
1912 |
| - "N\n", |
1913 |
| - "S\n", |
1914 |
| - "W\n", |
1915 |
| - "E\n", |
1916 |
| - "N\n", |
1917 |
| - "S\n" |
1918 |
| - ] |
1919 |
| - } |
1920 |
| - ], |
1921 |
| - "source": [ |
1922 |
| - "for i in range(10):\n", |
1923 |
| - " print(next(iter_cycl))" |
1924 |
| - ] |
1925 |
| - }, |
1926 |
| - { |
1927 |
| - "cell_type": "markdown", |
1928 |
| - "metadata": {}, |
1929 |
| - "source": [ |
1930 |
| - "So, now we can tackle our original problem:" |
1931 |
| - ] |
1932 |
| - }, |
1933 |
| - { |
1934 |
| - "cell_type": "code", |
1935 |
| - "execution_count": 26, |
1936 |
| - "metadata": {}, |
1937 |
| - "outputs": [ |
1938 |
| - { |
1939 |
| - "name": "stdout", |
1940 |
| - "output_type": "stream", |
1941 |
| - "text": [ |
1942 |
| - "1N\n", |
1943 |
| - "2S\n", |
1944 |
| - "3W\n", |
1945 |
| - "4E\n", |
1946 |
| - "5N\n", |
1947 |
| - "6S\n", |
1948 |
| - "7W\n", |
1949 |
| - "8E\n", |
1950 |
| - "9N\n", |
1951 |
| - "10S\n" |
1952 |
| - ] |
1953 |
| - } |
1954 |
| - ], |
1955 |
| - "source": [ |
1956 |
| - "n = 10\n", |
1957 |
| - "iter_cycl = CyclicIterator('NSWE')\n", |
1958 |
| - "for i in range(1, n+1):\n", |
1959 |
| - " direction = next(iter_cycl)\n", |
1960 |
| - " print(f'{i}{direction}')" |
1961 |
| - ] |
1962 |
| - }, |
1963 |
| - { |
1964 |
| - "cell_type": "markdown", |
1965 |
| - "metadata": {}, |
1966 |
| - "source": [ |
1967 |
| - "And re-working this into a list comprehension:" |
1968 |
| - ] |
1969 |
| - }, |
1970 |
| - { |
1971 |
| - "cell_type": "code", |
1972 |
| - "execution_count": 27, |
1973 |
| - "metadata": {}, |
1974 |
| - "outputs": [ |
1975 |
| - { |
1976 |
| - "data": { |
1977 |
| - "text/plain": [ |
1978 |
| - "['1N', '2S', '3W', '4E', '5N', '6S', '7W', '8E', '9N', '10S']" |
1979 |
| - ] |
1980 |
| - }, |
1981 |
| - "execution_count": 27, |
1982 |
| - "metadata": {}, |
1983 |
| - "output_type": "execute_result" |
1984 |
| - } |
1985 |
| - ], |
1986 |
| - "source": [ |
1987 |
| - "n = 10\n", |
1988 |
| - "iter_cycl = CyclicIterator('NSWE')\n", |
1989 |
| - "[f'{i}{next(iter_cycl)}' for i in range(1, n+1)]" |
1990 |
| - ] |
1991 |
| - }, |
1992 |
| - { |
1993 |
| - "cell_type": "markdown", |
1994 |
| - "metadata": {}, |
1995 |
| - "source": [ |
1996 |
| - "Of course, there's an easy alternative way to do this as well, using:\n", |
1997 |
| - "* repetition\n", |
1998 |
| - "* zip\n", |
1999 |
| - "* a list comprehension" |
2000 |
| - ] |
2001 |
| - }, |
2002 |
| - { |
2003 |
| - "cell_type": "markdown", |
2004 |
| - "metadata": {}, |
2005 |
| - "source": [ |
2006 |
| - "We need to repeat the array ['N', 'S', 'W', 'E'] for as many times as we have elements in our range of integers - we can even create way more than we need - because when we `zip` it up with the range of integers, the smallest length iterable will be used:" |
2007 |
| - ] |
2008 |
| - }, |
2009 |
| - { |
2010 |
| - "cell_type": "code", |
2011 |
| - "execution_count": 28, |
2012 |
| - "metadata": {}, |
2013 |
| - "outputs": [ |
2014 |
| - { |
2015 |
| - "data": { |
2016 |
| - "text/plain": [ |
2017 |
| - "[(1, 'N'),\n", |
2018 |
| - " (2, 'S'),\n", |
2019 |
| - " (3, 'W'),\n", |
2020 |
| - " (4, 'E'),\n", |
2021 |
| - " (5, 'N'),\n", |
2022 |
| - " (6, 'S'),\n", |
2023 |
| - " (7, 'W'),\n", |
2024 |
| - " (8, 'E'),\n", |
2025 |
| - " (9, 'N'),\n", |
2026 |
| - " (10, 'S')]" |
2027 |
| - ] |
2028 |
| - }, |
2029 |
| - "execution_count": 28, |
2030 |
| - "metadata": {}, |
2031 |
| - "output_type": "execute_result" |
2032 |
| - } |
2033 |
| - ], |
2034 |
| - "source": [ |
2035 |
| - "n = 10\n", |
2036 |
| - "list(zip(range(1, n+1), 'NSWE' * (n//4 + 1)))" |
2037 |
| - ] |
2038 |
| - }, |
2039 |
| - { |
2040 |
| - "cell_type": "code", |
2041 |
| - "execution_count": 29, |
2042 |
| - "metadata": {}, |
2043 |
| - "outputs": [ |
2044 |
| - { |
2045 |
| - "data": { |
2046 |
| - "text/plain": [ |
2047 |
| - "['1N', '2S', '3W', '4E', '5N', '6S', '7W', '8E', '9N', '10S']" |
2048 |
| - ] |
2049 |
| - }, |
2050 |
| - "execution_count": 29, |
2051 |
| - "metadata": {}, |
2052 |
| - "output_type": "execute_result" |
2053 |
| - } |
2054 |
| - ], |
2055 |
| - "source": [ |
2056 |
| - "[f'{i}{direction}'\n", |
2057 |
| - " for i, direction in zip(range(1, n+1), 'NSWE' * (n//4 + 1))]" |
2058 |
| - ] |
2059 |
| - }, |
2060 |
| - { |
2061 |
| - "cell_type": "markdown", |
2062 |
| - "metadata": {}, |
2063 |
| - "source": [ |
2064 |
| - "There's actually an even easier way yet, and that's to use our `CyclicIterator`, but instead of building it ourselves, we can simply use the one provided by Python in the standard library!!" |
2065 |
| - ] |
2066 |
| - }, |
2067 |
| - { |
2068 |
| - "cell_type": "code", |
2069 |
| - "execution_count": 30, |
2070 |
| - "metadata": { |
2071 |
| - "collapsed": true |
2072 |
| - }, |
2073 |
| - "outputs": [], |
2074 |
| - "source": [ |
2075 |
| - "import itertools" |
2076 |
| - ] |
2077 |
| - }, |
2078 |
| - { |
2079 |
| - "cell_type": "code", |
2080 |
| - "execution_count": 31, |
2081 |
| - "metadata": {}, |
2082 |
| - "outputs": [ |
2083 |
| - { |
2084 |
| - "data": { |
2085 |
| - "text/plain": [ |
2086 |
| - "['1N', '2S', '3W', '4E', '5N', '6S', '7W', '8E', '9N', '10S']" |
2087 |
| - ] |
2088 |
| - }, |
2089 |
| - "execution_count": 31, |
2090 |
| - "metadata": {}, |
2091 |
| - "output_type": "execute_result" |
2092 |
| - } |
2093 |
| - ], |
2094 |
| - "source": [ |
2095 |
| - "n = 10\n", |
2096 |
| - "iter_cycl = CyclicIterator('NSWE')\n", |
2097 |
| - "[f'{i}{next(iter_cycl)}' for i in range(1, n+1)]" |
2098 |
| - ] |
2099 |
| - }, |
2100 |
| - { |
2101 |
| - "cell_type": "markdown", |
2102 |
| - "metadata": {}, |
2103 |
| - "source": [ |
2104 |
| - "and using itertools:" |
2105 |
| - ] |
2106 |
| - }, |
2107 |
| - { |
2108 |
| - "cell_type": "code", |
2109 |
| - "execution_count": 32, |
2110 |
| - "metadata": {}, |
2111 |
| - "outputs": [ |
2112 |
| - { |
2113 |
| - "data": { |
2114 |
| - "text/plain": [ |
2115 |
| - "['1N', '2S', '3W', '4E', '5N', '6S', '7W', '8E', '9N', '10S']" |
2116 |
| - ] |
2117 |
| - }, |
2118 |
| - "execution_count": 32, |
2119 |
| - "metadata": {}, |
2120 |
| - "output_type": "execute_result" |
2121 |
| - } |
2122 |
| - ], |
2123 |
| - "source": [ |
2124 |
| - "n = 10\n", |
2125 |
| - "iter_cycl = itertools.cycle('NSWE')\n", |
2126 |
| - "[f'{i}{next(iter_cycl)}' for i in range(1, n+1)]" |
2127 |
| - ] |
2128 | 1830 | }
|
2129 | 1831 | ],
|
2130 | 1832 | "metadata": {
|
|
0 commit comments