<jupyter_start><jupyter_text>Lists and Tuples===In this notebook, you will learn to store more than one valuable in a single variable. This by itself is one of the most powerful ideas in programming, and it introduces a number of other central concepts such as loops. If this section ends up making sense to you, you will be able to start writing some interesting programs, and you can be more confident that you will be able to develop overall competence as a programmer.This lecture includes only a basic introduction to Lists and Tuples - you should also look at the supplementary lecture [More Lists and Tuples]() [Previous: Variables, Strings, and Numbers]() | [Home]() | [Next: Introducing Functions]() Contents===- [Lists](Lists)    - [Introducing Lists](Introducing-Lists)        - [Example](Example)        - [Naming and defining a list](Naming-and-defining-a-list)        - [Accessing one item in a list](Accessing-one-item-in-a-list)        - [Exercises](Exercises-lists)    - [Lists and Looping](Lists-and-Looping)        - [Accessing all elements in a list](Accessing-all-elements-in-a-list)        - [Enumerating a list](Enumerating-a-list)        - [Exercises](Exercises-loops)    - [Common List Operations](Common-List-Operations)        - [Modifying elements in a list](Modifying-elements-in-a-list)        - [Finding an element in a list](Finding-an-element-in-a-list)        - [Testing whether an element is in a list](Testing-whether-an-element-is-in-a-list)        - [Adding items to a list](Adding-items-to-a-list)        - [Creating an empty list](Creating-an-empty-list)        - [Sorting a list](Sorting-a-list)        - [Finding the length of a list](Finding-the-length-of-a-list)    - [Numerical Lists](Numerical-Lists)        - [The *range()* function](The_range_function)        - [The *min()*, *max()*, *sum()* functions](Min_max_sum)        - [Exercises](Exercises-numerical)    - [Tuples](Tuples)        - [Defining tuples, and accessing elements](Defining-tuples,-and-accessing-elements)        - [Using tuples to make strings](Using-tuples-to-make-strings)    - [Coding Style](Coding-Style)        - [Why have style conventions?](Why-have-style-conventions?)        - [What is a PEP?](What-is-a-PEP?)        - [Basic Python style guidelines](Basic-Python-style-guidelines)        - [Exercises](Exercises-pep8)    - [Overall Challenges](Overall-Challenges) Lists=== Introducing Lists===Example---A list is a collection of items, that is stored in a variable. The items should be related in some way, but there are no restrictions on what can be stored in a list. Here is a simple example of a list, and how we can quickly access each item in the list.<jupyter_code>students = ['bernice', 'aaron', 'cody']

for student in students:
    print("Hello, " + student.title() + "!")<jupyter_output><empty_output><jupyter_text>Naming and defining a list---Since lists are collection of objects, it is good practice to give them a plural name. If each item in your list is a car, call the list 'cars'. If each item is a dog, call your list 'dogs'. This gives you a straightforward way to refer to the entire list ('dogs'), and to a single item in the list ('dog').In Python, square brackets designate a list. To define a list, you give the name of the list, the equals sign, and the values you want to include in your list within square brackets.<jupyter_code>dogs = ['border collie', 'australian cattle dog', 'labrador retriever']<jupyter_output><empty_output><jupyter_text>Accessing one item in a list---Items in a list are identified by their position in the list, starting with zero. This will almost certainly trip you up at some point. Programmers even joke about how often we all make "off-by-one" errors, so don't feel bad when you make this kind of error.To access the first element in a list, you give the name of the list, followed by a zero in parentheses.<jupyter_code>dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

dog = dogs[0]
print(dog.title())<jupyter_output><empty_output><jupyter_text>The number in parentheses is called the **index** of the item. Because lists start at zero, the index of an item is always one less than its position in the list. So to get the second item in the list, we need to use an index of 1.<jupyter_code>###highlight=[4]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

dog = dogs[1]
print(dog.title())<jupyter_output><empty_output><jupyter_text>Accessing the last items in a listYou can probably see that to get the last item in this list, we would use an index of 2. This works, but it would only work because our list has exactly three items. To get the last item in a list, no matter how long the list is, you can use an index of -1.<jupyter_code>###highlight=[4]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

dog = dogs[-1]
print(dog.title())<jupyter_output><empty_output><jupyter_text>This syntax also works for the second to last item, the third to last, and so forth.<jupyter_code>###highlight=[4]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

dog = dogs[-2]
print(dog.title())<jupyter_output><empty_output><jupyter_text>You can't use a negative number larger than the length of the list, however.<jupyter_code>###highlight=[4]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

dog = dogs[-4]
print(dog.title())<jupyter_output><empty_output><jupyter_text>Exercises--- First List- Store the values 'python', 'c', and 'java' in a list. Print each of these values out, using their position in the list.  First Neat List- Store the values 'python', 'c', and 'java' in a list. Print a statement about each of these values, using their position in the list.- Your statement could simply be, 'A nice programming language is *value*.'  Your First List- Think of something you can store in a list. Make a list with three or four items, and then print a message that includes at least one item from your list. Your sentence could be as simple as, "One item in my list is a ____." Lists and Looping=== Accessing all elements in a list---This is one of the most important concepts related to lists. You can have a list with a million items in it, and in three lines of code you can write a sentence for each of those million items. If you want to understand lists, and become a competent programmer, make sure you take the time to understand this section.We use a loop to access all the elements in a list. A loop is a block of code that repeats itself until it runs out of items to work with, or until a certain condition is met. In this case, our loop will run once for every item in our list. With a list that is three items long, our loop will run three times.Let's take a look at how we access all the items in a list, and then try to understand how it works.<jupyter_code>dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

for dog in dogs:
    print(dog)<jupyter_output><empty_output><jupyter_text>We have already seen how to create a list, so we are really just trying to understand how the last two lines work. These last two lines make up a loop, and the language here can help us see what is happening:    for dog in dogs:- The keyword "for" tells Python to get ready to use a loop.- The variable "dog", with no "s" on it, is a temporary placeholder variable. This is the variable that Python will place each item in the list into, one at a time.- The first time through the loop, the value of "dog" will be 'border collie'.- The second time through the loop, the value of "dog" will be 'australian cattle dog'.- The third time through, "dog" will be 'labrador retriever'.- After this, there are no more items in the list, and the loop will end.The site pythontutor.com allows you to run Python code one line at a time. As you run the code, there is also a visualization on the screen that shows you how the variable "dog" holds different values as the loop progresses. There is also an arrow that moves around your code, showing you how some lines are run just once, while other lines are run multiple tiimes. If you would like to see this in action, click the Forward button and watch the visualization, and the output as it is printed to the screen. Tools like this are incredibly valuable for seeing what Python is doing with your code. Doing more with each itemWe can do whatever we want with the value of "dog" inside the loop. In this case, we just print the name of the dog.    print(dog)We are not limited to just printing the word dog. We can do whatever we want with this value, and this action will be carried out for every item in the list. Let's say something about each dog in our list.<jupyter_code>###highlight=[5]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

for dog in dogs:
    print('I like ' + dog + 's.')<jupyter_output><empty_output><jupyter_text>Visualize this on pythontutor. Inside and outside the loopPython uses indentation to decide what is inside the loop and what is outside the loop. Code that is inside the loop will be run for every item in the list. Code that is not indented, which comes after the loop, will be run once just like regular code.<jupyter_code>###highlight=[6,7,8]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

for dog in dogs:
    print('I like ' + dog + 's.')
    print('No, I really really like ' + dog +'s!\n')
    
print("\nThat's just how I feel about dogs.")<jupyter_output><empty_output><jupyter_text>Notice that the last line only runs once, after the loop is completed. Also notice the use of newlines ("\n") to make the output easier to read. Run this code on pythontutor. Enumerating a list---When you are looping through a list, you may want to know the index of the current item. You could always use the *list.index(value)* syntax, but there is a simpler way. The *enumerate()* function tracks the index of each item for you, as it loops through the list:<jupyter_code>dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

print("Results for the dog show are as follows:\n")
for index, dog in enumerate(dogs):
    place = str(index)
    print("Place: " + place + " Dog: " + dog.title())<jupyter_output><empty_output><jupyter_text>To enumerate a list, you need to add an *index* variable to hold the current index. So instead of    for dog in dogs:    You have    for index, dog in enumerate(dogs)    The value in the variable *index* is always an integer. If you want to print it in a string, you have to turn the integer into a string:    str(index)    The index always starts at 0, so in this example the value of *place* should actually be the current index, plus one:<jupyter_code>###highlight=[6]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

print("Results for the dog show are as follows:\n")
for index, dog in enumerate(dogs):
    place = str(index + 1)
    print("Place: " + place + " Dog: " + dog.title())<jupyter_output><empty_output><jupyter_text>A common looping errorOne common looping error occurs when instead of using the single variable *dog* inside the loop, we accidentally use the variable that holds the entire list:<jupyter_code>###highlight=[5]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

for dog in dogs:
    print(dogs)<jupyter_output><empty_output><jupyter_text>In this example, instead of printing each dog in the list, we print the entire list every time we go through the loop. Python puts each individual item in the list into the variable *dog*, but we never use that variable. Sometimes you will just get an error if you try to do this:<jupyter_code>###highlight=[5]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

for dog in dogs:
    print('I like ' + dogs + 's.')<jupyter_output><empty_output><jupyter_text>Exercises--- First List - Loop- Repeat *First List*, but this time use a loop to print out each value in the list.  First Neat List - Loop- Repeat *First Neat List*, but this time use a loop to print out your statements. Make sure you are writing the same sentence for all values in your list. Loops are not effective when you are trying to generate different output for each value in your list.  Your First List - Loop- Repeat *Your First List*, but this time use a loop to print out your message for each item in your list. Again, if you came up with different messages for each value in your list, decide on one message to repeat for each value in your list. Common List Operations=== Modifying elements in a list---You can change the value of any element in a list if you know the position of that item.<jupyter_code>dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

dogs[0] = 'australian shepherd'
print(dogs)<jupyter_output><empty_output><jupyter_text>Finding an element in a list---If you want to find out the position of an element in a list, you can use the index() function.<jupyter_code>dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

print(dogs.index('australian cattle dog'))<jupyter_output><empty_output><jupyter_text>This method returns a ValueError if the requested item is not in the list.<jupyter_code>###highlight=[4]
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

print(dogs.index('poodle'))<jupyter_output><empty_output><jupyter_text>Testing whether an item is in a list---You can test whether an item is in a list using the "in" keyword. This will become more useful after learning how to use if-else statements.<jupyter_code>dogs = ['border collie', 'australian cattle dog', 'labrador retriever']

print('australian cattle dog' in dogs)
print('poodle' in dogs)<jupyter_output><empty_output><jupyter_text>Adding items to a list--- Appending items to the end of a listWe can add an item to a list using the append() method. This method adds the new item to the end of the list.<jupyter_code>dogs = ['border collie', 'australian cattle dog', 'labrador retriever']
dogs.append('poodle')

for dog in dogs:
    print(dog.title() + "s are cool.")<jupyter_output><empty_output><jupyter_text>Inserting items into a listWe can also insert items anywhere we want in a list, using the **insert()** function. We specify the position we want the item to have, and everything from that point on is shifted one position to the right. In other words, the index of every item after the new item is increased by one.<jupyter_code>dogs = ['border collie', 'australian cattle dog', 'labrador retriever']
dogs.insert(1, 'poodle')

print(dogs)<jupyter_output><empty_output><jupyter_text>Note that you have to give the position of the new item first, and then the value of the new item. If you do it in the reverse order, you will get an error. Creating an empty list---Now that we know how to add items to a list after it is created, we can use lists more dynamically. We are no longer stuck defining our entire list at once.A common approach with lists is to define an empty list, and then let your program add items to the list as necessary. This approach works, for example, when starting to build an interactive web site. Your list of users might start out empty, and then as people register for the site it will grow. This is a simplified approach to how web sites actually work, but the idea is realistic.Here is a brief example of how to start with an empty list, start to fill it up, and work with the items in the list. The only new thing here is the way we define an empty list, which is just an empty set of square brackets.<jupyter_code># Create an empty list to hold our users.
usernames = []

# Add some users.
usernames.append('bernice')
usernames.append('cody')
usernames.append('aaron')

# Greet all of our users.
for username in usernames:
    print("Welcome, " + username.title() + '!')<jupyter_output><empty_output><jupyter_text>If we don't change the order in our list, we can use the list to figure out who our oldest and newest users are.<jupyter_code>###highlight=[10,11,12]
# Create an empty list to hold our users.
usernames = []

# Add some users.
usernames.append('bernice')
usernames.append('cody')
usernames.append('aaron')

# Greet all of our users.
for username in usernames:
    print("Welcome, " + username.title() + '!')

# Recognize our first user, and welcome our newest user.
print("\nThank you for being our very first user, " + usernames[0].title() + '!')
print("And a warm welcome to our newest user, " + usernames[-1].title() + '!')<jupyter_output><empty_output><jupyter_text>Note that the code welcoming our newest user will always work, because we have used the index -1. If we had used the index 2 we would always get the third user, even as our list of users grows and grows. Sorting a List---We can sort a list alphabetically, in either order.<jupyter_code>students = ['bernice', 'aaron', 'cody']

# Put students in alphabetical order.
students.sort()

# Display the list in its current order.
print("Our students are currently in alphabetical order.")
for student in students:
    print(student.title())

#Put students in reverse alphabetical order.
students.sort(reverse=True)

# Display the list in its current order.
print("\nOur students are now in reverse alphabetical order.")
for student in students:
    print(student.title())<jupyter_output><empty_output><jupyter_text>*sorted()* vs. *sort()*Whenever you consider sorting a list, keep in mind that you can not recover the original order. If you want to display a list in sorted order, but preserve the original order, you can use the *sorted()* function. The *sorted()* function also accepts the optional *reverse=True* argument.<jupyter_code>students = ['bernice', 'aaron', 'cody']

# Display students in alphabetical order, but keep the original order.
print("Here is the list in alphabetical order:")
for student in sorted(students):
    print(student.title())

# Display students in reverse alphabetical order, but keep the original order.
print("\nHere is the list in reverse alphabetical order:")
for student in sorted(students, reverse=True):
    print(student.title())

print("\nHere is the list in its original order:")
# Show that the list is still in its original order.
for student in students:
    print(student.title())<jupyter_output><empty_output><jupyter_text>Reversing a listWe have seen three possible orders for a list:- The original order in which the list was created- Alphabetical order- Reverse alphabetical orderThere is one more order we can use, and that is the reverse of the original order of the list. The *reverse()* function gives us this order.<jupyter_code>students = ['bernice', 'aaron', 'cody']
students.reverse()

print(students)<jupyter_output><empty_output><jupyter_text>Note that reverse is permanent, although you could follow up with another call to *reverse()* and get back the original order of the list.  Sorting a numerical listAll of the sorting functions work for numerical lists as well.<jupyter_code>numbers = [1, 3, 4, 2]

# sort() puts numbers in increasing order.
numbers.sort()
print(numbers)

# sort(reverse=True) puts numbers in decreasing order.
numbers.sort(reverse=True)
print(numbers)

numbers = [1, 3, 4, 2]

# sorted() preserves the original order of the list:
print(sorted(numbers))
print(numbers)
numbers = [1, 3, 4, 2]

# The reverse() function also works for numerical lists.
numbers.reverse()
print(numbers)<jupyter_output><empty_output><jupyter_text>Finding the length of a list---You can find the length of a list using the *len()* function.<jupyter_code>usernames = ['bernice', 'cody', 'aaron']
user_count = len(usernames)

print(user_count)<jupyter_output><empty_output><jupyter_text>There are many situations where you might want to know how many items in a list. If you have a list that stores your users, you can find the length of your list at any time, and know how many users you have.<jupyter_code># Create an empty list to hold our users.
usernames = []

# Add some users, and report on how many users we have.
usernames.append('bernice')
user_count = len(usernames)

print("We have " + str(user_count) + " user!")

usernames.append('cody')
usernames.append('aaron')
user_count = len(usernames)

print("We have " + str(user_count) + " users!")<jupyter_output><empty_output><jupyter_text>On a technical note, the *len()* function returns an integer, which can't be printed directly with strings. We use the *str()* function to turn the integer into a string so that it prints nicely:<jupyter_code>usernames = ['bernice', 'cody', 'aaron']
user_count = len(usernames)

print("This will cause an error: " + user_count)
###highlight=[5]
usernames = ['bernice', 'cody', 'aaron']
user_count = len(usernames)

print("This will work: " + str(user_count))<jupyter_output><empty_output><jupyter_text>Numerical Lists===There is nothing special about lists of numbers, but there are some functions you can use to make working with numerical lists more efficient. Let's make a list of the first ten numbers, and start working with it to see how we can use numbers in a list.<jupyter_code># Print out the first ten numbers.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for number in numbers:
    print(number)<jupyter_output><empty_output><jupyter_text>The *range()* function---This works, but it is not very efficient if we want to work with a large set of numbers. The *range()* function helps us generate long lists of numbers. Here are two ways to do the same thing, using the *range* function.<jupyter_code># Print the first ten numbers.
for number in range(1,11):
    print(number)<jupyter_output><empty_output><jupyter_text>The range function takes in a starting number, and an end number. You get all integers, up to but not including the end number. You can also add a *step* value, which tells the *range* function how big of a step to take between numbers:<jupyter_code># Print the first ten odd numbers.
for number in range(1,21,2):
    print(number)<jupyter_output><empty_output><jupyter_text>If we want to store these numbers in a list, we can use the *list()* function. This function takes in a range, and turns it into a list:<jupyter_code># Create a list of the first ten numbers.
numbers = list(range(1,11))
print(numbers)<jupyter_output><empty_output><jupyter_text>This is incredibly powerful; we can now create a list of the first million numbers, just as easily as we made a list of the first ten numbers. It doesn't really make sense to print the million numbers here, but we can show that the list really does have one million items in it, and we can print the last ten items to show that the list is correct.<jupyter_code># Store the first million numbers in a list.
numbers = list(range(1,1000001))

# Show the length of the list:
print("The list 'numbers' has " + str(len(numbers)) + " numbers in it.")

# Show the last ten numbers:
print("\nThe last ten numbers in the list are:")
for number in numbers[-10:]:
    print(number)<jupyter_output><empty_output><jupyter_text>There are two things here that might be a little unclear. The expression    str(len(numbers))takes the length of the *numbers* list, and turns it into a string that can be printed.The expression     numbers[-10:]gives us a *slice* of the list. The index `-1` is the last item in the list, and the index `-10` is the item ten places from the end of the list. So the slice `numbers[-10:]` gives us everything from that item to the end of the list. The *min()*, *max()*, and *sum()* functions---There are three functions you can easily use with numerical lists. As you might expect, the *min()* function returns the smallest number in the list, the *max()* function returns the largest number in the list, and the *sum()* function returns the total of all numbers in the list.<jupyter_code>ages = [23, 16, 14, 28, 19, 11, 38]

youngest = min(ages)
oldest = max(ages)
total_years = sum(ages)

print("Our youngest reader is " + str(youngest) + " years old.")
print("Our oldest reader is " + str(oldest) + " years old.")
print("Together, we have " + str(total_years) + " years worth of life experience.")<jupyter_output><empty_output><jupyter_text>Exercises--- First Twenty- Use the *range()* function to store the first twenty numbers (1-20) in a list, and print them out.  Five Wallets- Imagine five wallets with different amounts of cash in them. Store these five values in a list, and print out the following sentences:    - "The fattest wallet has $ *value* in it."    - "The skinniest wallet has $ *value* in it."    - "All together, these wallets have $ *value* in them." Tuples===Tuples are basically lists that can never be changed. Lists are quite dynamic; they can grow as you append and insert items, and they can shrink as you remove items. You can modify any element you want to in a list. Sometimes we like this behavior, but other times we may want to ensure that no user or no part of a program can change a list. That's what tuples are for.Technically, lists are *mutable* objects and tuples are *immutable* objects. Mutable objects can change (think of *mutations*), and immutable objects can not change.Defining tuples, and accessing elements---You define a tuple just like you define a list, except you use parentheses instead of square brackets. Once you have a tuple, you can access individual elements just like you can with a list, and you can loop through the tuple with a *for* loop:<jupyter_code>colors = ('red', 'green', 'blue')
print("The first color is: " + colors[0])

print("\nThe available colors are:")
for color in colors:
    print("- " + color)<jupyter_output><empty_output><jupyter_text>If you try to add something to a tuple, you will get an error:<jupyter_code>colors = ('red', 'green', 'blue')
colors.append('purple')<jupyter_output><empty_output><jupyter_text>The same kind of thing happens when you try to remove something from a tuple, or modify one of its elements. Once you define a tuple, you can be confident that its values will not change. Using tuples to make strings---We have seen that it is pretty useful to be able to mix raw English strings with values that are stored in variables, as in the following:<jupyter_code>animal = 'dog'
print("I have a " + animal + ".")<jupyter_output><empty_output><jupyter_text>This was especially useful when we had a series of similar statements to make:<jupyter_code>animals = ['dog', 'cat', 'bear']
for animal in animals:
    print("I have a " + animal + ".")<jupyter_output><empty_output><jupyter_text>I like this approach of using the plus sign to build strings because it is fairly intuitive. We can see that we are adding several smaller strings together to make one longer string. This is intuitive, but it is a lot of typing. There is a shorter way to do this, using *placeholders*.Python ignores most of the characters we put inside of strings. There are a few characters that Python pays attention to, as we saw with strings such as "\t" and "\n". Python also pays attention to "%s" and "%d". These are placeholders. When Python sees the "%s" placeholder, it looks ahead and pulls in the first argument after the % sign:<jupyter_code>animal = 'dog'
print("I have a %s." % animal)<jupyter_output><empty_output><jupyter_text>This is a much cleaner way of generating strings that include values. We compose our sentence all in one string, and then tell Python what values to pull into the string, in the appropriate places.This is called *string formatting*, and it looks the same when you use a list:<jupyter_code>animals = ['dog', 'cat', 'bear']
for animal in animals:
    print("I have a %s." % animal)<jupyter_output><empty_output><jupyter_text>If you have more than one value to put into the string you are composing, you have to pack the values into a tuple:<jupyter_code>animals = ['dog', 'cat', 'bear']
print("I have a %s, a %s, and a %s." % (animals[0], animals[1], animals[2]))<jupyter_output><empty_output><jupyter_text>String formatting with numbersIf you recall, printing a number with a string can cause an error:<jupyter_code>number = 23
print("My favorite number is " + number + ".")<jupyter_output><empty_output><jupyter_text>Python knows that you could be talking about the value 23, or the characters '23'. So it throws an error, forcing us to clarify that we want Python to treat the number as a string. We do this by *casting* the number into a string using the *str()* function:<jupyter_code>###highlight=[3]
number = 23
print("My favorite number is " + str(number) + ".")<jupyter_output><empty_output><jupyter_text>The format string "%d" takes care of this for us. Watch how clean this code is:<jupyter_code>###highlight=[3]
number = 23
print("My favorite number is %d." % number)<jupyter_output><empty_output><jupyter_text>If you want to use a series of numbers, you pack them into a tuple just like we saw with strings:<jupyter_code>numbers = [7, 23, 42]
print("My favorite numbers are %d, %d, and %d." % (numbers[0], numbers[1], numbers[2]))<jupyter_output><empty_output><jupyter_text>Just for clarification, look at how much longer the code is if you use concatenation instead of string formatting:<jupyter_code>###highlight=[3]
numbers = [7, 23, 42]
print("My favorite numbers are " + str(numbers[0]) + ", " + str(numbers[1]) + ", and " + str(numbers[2]) + ".")<jupyter_output><empty_output><jupyter_text>You can mix string and numerical placeholders in any order you want.<jupyter_code>names = ['eric', 'ever']
numbers = [23, 2]
print("%s's favorite number is %d, and %s's favorite number is %d." % (names[0].title(), numbers[0], names[1].title(), numbers[1]))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09267881241565452, 'fraction_numerical': 0.004824561403508772, 'mean_word_length': 4.703482778526073, 'pattern_counts': {'":': 0, '<': 193, '<?xml version=': 0, '>': 193, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '48', 'dir': 'jupyter-structured-clean-dedup', 'id': '535978', 'license': 'MIT', 'n_tokens_mistral': 8688, 'n_tokens_neox': 8436, 'n_words': 4111, 'path': 'notebooks/lists_tuples.ipynb', 'repo_name': 'dlivingstone/IntroToPython', 'size': '29640'}