メモ「Automate the Boring stuff -chapter4 Lists」

# The List Data Type

1. The term list value refers to the list itself (which is a value that can be stored in a variable or passed to a function like any other value), not the values inside the list value.

1. Python will give you an IndexError error message if you use an index that exceeds the number of values in your list value.

1. Indexes can be only integer values, not floats. The following example will cause a TypeError error

```
>>> spam = [['cat', 'bat'], [10, 20, 30, 40, 50]]
>>> spam[0]
['cat', 'bat']
>>> spam[0][1]
'bat'
>>> spam[1][4]
50
```

## Negative Indexes

- The integer value -1 refers to the last index in a list, the value -2 refers to the second-to-last index in a list, and so on.

## Getting Sublists with Slices

1. In a slice, the first integer is the index where the slice starts.

1. The second integer is the index where the slice ends.

1. A slice goes up to, but will not include, the value at the second index.

1. A slice evaluates to a new list value.

1. As a shortcut, you can leave out one or both of the indexes on either side of the colon in the slice.

## Getting a List’s Length with len()

- The len() function will return the number of values that are in a list value passed to it, just like it can count the number of characters in a string value.

## Changing Values in a List with Indexes

```
 >>> spam = ['cat', 'bat', 'rat', 'elephant']
>>> spam[1] = 'aardvark'
>>> spam
['cat', 'aardvark', 'rat', 'elephant']
>>> spam[2] = spam[1]
>>> spam
['cat', 'aardvark', 'aardvark', 'elephant']
>>> spam[-1] = 12345
>>> spam
['cat', 'aardvark', 'aardvark', 12345]
```

## List Concatenation and List Replication

```
>>> [1, 2, 3] + ['A', 'B', 'C']
[1, 2, 3, 'A', 'B', 'C']
>>> ['X', 'Y', 'Z'] * 3
['X', 'Y', 'Z', 'X', 'Y', 'Z', 'X', 'Y', 'Z']
>>> spam = [1, 2, 3]
>>> spam = spam + ['A', 'B', 'C']
>>> spam
[1, 2, 3, 'A', 'B', 'C']
```

## Removing Values from Lists with del Statements

```
>>> spam = ['cat', 'bat', 'rat', 'elephant']
>>> del spam[2]
>>> spam
['cat', 'bat', 'elephant']
>>> del spam[2]
>>> spam
['cat', 'bat']
```

# Working with Lists

```
catNames = []
while True:
    print('Enter the name of cat ' + str(len(catNames) + 1) +
      ' (Or enter nothing to stop.):')
    name = input()
    if name == '':
        break
    catNames = catNames + [name] # list concatenation
print('The cat names are:')
for name in catNames:
    print('  ' + name)


Enter the name of cat 1 (Or enter nothing to stop.):
Zophie
Enter the name of cat 2 (Or enter nothing to stop.):
Pooka
Enter the name of cat 3 (Or enter nothing to stop.):
Simon
Enter the name of cat 4 (Or enter nothing to stop.):
Lady Macbeth
Enter the name of cat 5 (Or enter nothing to stop.):
Fat-tail
Enter the name of cat 6 (Or enter nothing to stop.):
Miss Cleo
Enter the name of cat 7 (Or enter nothing to stop.):

The cat names are:
  Zophie
  Pooka
  Simon
  Lady Macbeth
  Fat-tail
  Miss Cleo
```
- catNames = [Zophie, Pooka, Simon, Lady Macbeth, Fat-tail, Miss Cleo]
- catNames contains 6 string values in the list, so the for Loops extract and print the values 6 times.

## Using for Loops with Lists

```
>>> supplies = ['pens', 'staplers', 'flame-throwers', 'binders']
>>> for i in range(len(supplies)):
    print('Index ' + str(i) + ' in supplies is: ' + supplies[i])

Index 0 in supplies is: pens
Index 1 in supplies is: staplers
Index 2 in supplies is: flame-throwers
Index 3 in supplies is: binders
```

## The in and not in Operators

```
myPets = ['Zophie', 'Pooka', 'Fat-tail']
print('Enter a pet name:')
name = input()
if name not in myPets:
    print('I do not have a pet named ' + name)
else:
    print(name + ' is my pet.')
The output may look something like this:


Enter a pet name:
Footfoot
I do not have a pet named Footfoot
```

## The Multiple Assignment Trick

- The multiple assignment trick is a shortcut that lets you assign multiple variables with the values in a list in one line of code.

```
Instead of doing this:
>>> cat = ['fat', 'orange', 'loud']
>>> size = cat[0]
>>> color = cat[1]
>>> disposition = cat[2]

you could type this line of code:

>>> cat = ['fat', 'orange', 'loud']
>>> size, color, disposition = cat
```

## Augmented Assignment Operators

`Augmented assignment statement　　Equivalent assignment statement`

spam += 1　　spam = spam + 1
spam -= 1　　spam = spam - 1
spam *= 1　　spam = spam * 1
spam /= 1　　spam = spam / 1
spam %= 1　　spam = spam % 1

# Methods

- A method is the same thing as a function, except it is “called on” a value.

- Each data type has its own set of methods. The list data type, for example, has several useful methods for finding, adding, removing, and otherwise manipulating values in a list.

## Finding a Value in a List with the index() Method

- List values have an index() method that can be passed a value, and if that value exists in the list, the index of the value is returned. If the value isn’t in the list, then Python produces a ValueError error.

- When there are duplicates of the value in the list, the index of its first appearance is returned.

## Adding Values to Lists with the append() and insert() Methods

```
>>> spam = ['cat', 'dog', 'bat']
>>> spam.append('moose')
>>> spam
['cat', 'dog', 'bat', 'moose']
```

```
>>> spam = ['cat', 'dog', 'bat']
>>> spam.insert(1, 'chicken')
>>> spam
['cat', 'chicken', 'dog', 'bat']
```

- Methods belong to a single data type. The append() and insert() methods are list methods and can be called only on list values, not on other values such as strings or integers.


## Removing Values from Lists with remove()

```
>>> spam = ['cat', 'bat', 'rat', 'elephant']
>>> spam.remove('bat')
>>> spam
['cat', 'rat', 'elephant']
```

1. If the value appears multiple times in the list, only the first instance of the value will be removed.

1. **The del statement is good to use when you know the index of the value you want to remove from the list. The remove() method is good when you know the value you want to remove from the list.**

## Sorting the Values in a List with the sort() Method

```
>>> spam = [2, 5, 3.14, 1, -7]
>>> spam.sort()
>>> spam
[-7, 1, 2, 3.14, 5]
>>> spam = ['ants', 'cats', 'dogs', 'badgers', 'elephants']
>>> spam.sort()
>>> spam
['ants', 'badgers', 'cats', 'dogs', 'elephants']


>>> spam.sort(reverse=True)
>>> spam
['elephants', 'dogs', 'cats', 'badgers', 'ants']


>>> spam = [1, 3, 2, 4, 'Alice', 'Bob']
>>> spam.sort()
Traceback (most recent call last):
 File "<pyshell#70>", line 1, in <module>
   spam.sort()
TypeError: unorderable types: str() < int()


>>> spam = ['Alice', 'ants', 'Bob', 'badgers', 'Carol', 'cats']
>>> spam.sort()
>>> spam
['Alice', 'Bob', 'Carol', 'ants', 'badgers', 'cats']


>>> spam = ['a', 'z', 'A', 'Z']
>>> spam.sort(key=str.lower)
>>> spam
['a', 'A', 'z', 'Z']
```

# Example Program: Magic 8 Ball with a List

## List-like Types: Strings and Tuples

# Mutable and Immutable Data Types

1. **A list value is a mutable data type: It can have values added, removed, or changed. However, a string is immutable: It cannot be changed.**

1. The proper way to “mutate” a string is to use slicing and concatenation to build a new string by copying from parts of the old string.

## The Tuple Data Type

1. If you need an ordered sequence of values that never changes, use a tuple.

1. A second benefit of using tuples instead of lists is that, because they are immutable and their contents don’t change, Python can implement some optimizations that make code using tuples slightly faster than code using lists.

## Converting Types with the list() and tuple() Functions

```
>>> tuple(['cat', 'dog', 5])
('cat', 'dog', 5)
>>> list(('cat', 'dog', 5))
['cat', 'dog', 5]
>>> list('hello')
['h', 'e', 'l', 'l', 'o']
```

## References

## Passing References

1. When a function is called, the values of the arguments are copied to the parameter variables.

1. For lists (and dictionaries, which I’ll describe in the next chapter), this means a copy of the reference is used for the parameter.

## The copy Module’s copy() and deepcopy() Functions

<a href="https://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-deepcopy-and-normal-assignm">What exactly is the difference between shallow copy, deepcopy and normal assignment operation?
</a>

# Summary

# Comma Code
https://www.geeksforgeeks.org/iterate-over-a-list-in-python/
```
def takeAListValue(param):
    length = len(param) -1
    for i in range(length):
        param[i] = param[i] + ', '
    param[-1] = 'and ' + param[-1]
    return param

spam = ['apples', 'bananas', 'tofu', 'cats']

code = ''
for j in takeAListValue(spam):
    code = code + j

print(code)
```

# Character Picture Grid

```
grid = [['.', '.', '.', '.', '.', '.'],
        ['.', 'O', 'O', '.', '.', '.'],
        ['O', 'O', 'O', 'O', '.', '.'],
        ['O', 'O', 'O', 'O', 'O', '.'],
        ['.', 'O', 'O', 'O', 'O', 'O'],
        ['O', 'O', 'O', 'O', 'O', '.'],
        ['O', 'O', 'O', 'O', '.', '.'],
        ['.', 'O', 'O', '.', '.', '.'],
        ['.', '.', '.', '.', '.', '.']]

x = len(grid) -1
y = len(grid[x]) -1
'''
print(x)
print(y)
'''
for i in range(0,y):
    for j in range(0,x):
        print(grid[j][i], end='')
    print()
```