Skip to the content.

Lists and filtering popcorn and hw hacks

This is a Jupyter Notebook where I blog my popcorn hacks.

# Popcorn Hack 1, Create a list of favorite movies
movies = ["Inception", "Titanic", "Avatar", "Up"]

# Replace the second movie with a new one
movies[1] = "Interstellar"

# Add another movie to the list
movies.append("Coco")

# Display the updated list
print(movies)

['Inception', 'Interstellar', 'Avatar', 'Up', 'Coco']
# Popcorn Hack 2 Given list of ages
ages = [15, 20, 34, 16, 18, 21, 14, 19]

# Create a new list with ages 18 or older
eligible_ages = [age for age in ages if age >= 18]

# Display the new list
print(eligible_ages)

[20, 34, 18, 21, 19]

Homework Hack 1 (extra credit for doing 8 bullet points)

Video 1:

  • In Python, lists are a built-in data structure for storing ordered data in a specific sequence.
  • Lists can be created using the list constructor or by using brackets, which is more common.
  • You can pre-populate a list with values or add new items later using the “append” method.
  • Lists preserve the order of data, unlike sets where order does not matter.
  • To access a specific value in a list, you use its index, starting from 0.
  • Python allows negative indices to access values from the end of a list, where -1 is the last item.
  • Slicing allows you to retrieve a range of values from a list, with the start index included and the end index excluded.
  • Lists in Python can contain different data types (integers, booleans, strings, floats) and even other lists, unlike some other languages that require lists to have uniform data types.

Video 2: #Key Takeaways from List Comprehensions in Python

  1. List Comprehension Syntax
    • A list comprehension is a concise way to create a list using the format:
      [expression for item in iterable]
      
    • Example: [n for n in nums] creates a copy of the list nums.
  2. Readable and Concise
    • List comprehensions are easier to read and write compared to traditional for loops. They allow you to condense the logic into a single line.
    • Example: Instead of writing a full loop to append squares of numbers, you can write:
      [n * n for n in nums]
      
  3. Handling Conditions in Comprehensions
    • You can include conditions in list comprehensions to filter elements.
    • Example: [n for n in nums if n % 2 == 0] returns only the even numbers from nums.
  4. Comparison to map and lambda Functions
    • While map() with lambda functions can be used to modify lists, list comprehensions are often more readable and intuitive.
    • Example:
      map(lambda n: n * n, nums)
      

      is harder to read than the list comprehension equivalent:

      [n * n for n in nums]
      
  5. Readability Over map()/lambda
    • List comprehensions are preferred for readability, especially for beginners, as the syntax directly expresses the transformation or filtering operation being done.
  6. Using Multiple Loops in a List Comprehension
    • You can use multiple for loops within a single list comprehension to generate combinations.
    • Example: [letter + str(number) for letter in 'ABC' for number in range(4)] generates all combinations like a0, a1, a2, a3, b0, b1, b2, b3, ....
  7. Avoiding map(), filter(), and lambda for Simplicity
    • In many cases, you can replace map(), filter(), and lambda with list comprehensions, simplifying the code and improving its readability.
  8. Efficiency Considerations
    • List comprehensions are often more efficient than using for loops, as they are optimized for creating lists in a single line of code.
#Homework Hack 2 
# Initialize a list containing numbers from 1 to 30
numbers = list(range(1, 31))

# Filter out numbers divisible by 3 but not by 5
filtered_numbers = [num for num in numbers if num % 3 == 0 and num % 5 != 0]

# Print both the original and filtered lists
print("Original List:", numbers)
print("Filtered List (divisible by 3 but not by 5):", filtered_numbers)

Original List: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
Filtered List (divisible by 3 but not by 5): [3, 6, 9, 12, 18, 21, 24, 27]
import pandas as pd

# Sample data to create the CSV file
data = {
    'song_name': ['Blinding Lights', 'Shape of You', 'Levitating', 'As It Was', 'Stay'],
    'streams': [32000000, 35000000, 15000000, 8000000, 12000000]
}

# Create a DataFrame from the data
df = pd.DataFrame(data)

# Save the DataFrame to a CSV file
df.to_csv('spotify_global_streaming_data_2024.csv', index=False)

print("CSV file 'spotify_global_streaming_data_2024.csv' has been created.")


CSV file 'spotify_global_streaming_data_2024.csv' has been created.
#Homework Hack 3
import pandas as pd

# Define the function to filter Spotify data
def filter_spotify_data(csv_file):
    # Read the CSV file into a DataFrame
    data = pd.read_csv(csv_file)
    
    # Filter the data to return songs with more than 10 million streams
    filtered_data = data[data['streams'] > 10000000]
    
    # Display the filtered data
    print("Songs with over 10 million streams:")
    print(filtered_data)

# Call the function with the CSV file path
filter_spotify_data('spotify_global_streaming_data_2024.csv')

Songs with over 10 million streams:
         song_name   streams
0  Blinding Lights  32000000
1     Shape of You  35000000
2       Levitating  15000000
4             Stay  12000000

Review questions:

  1. Explain what lists are in Python, including how to modify and manipulate them. In Python, lists are ordered collections of items, which can be of any data type, such as integers, strings, or even other lists. Lists are defined by enclosing elements in square brackets [], and items are separated by commas.

Modifying and Manipulating Lists: Accessing Elements: You can access list elements by their index. For example, my_list[0] returns the first element.

Modifying Elements: You can modify elements using their index, such as my_list[0] = 10, which changes the first element to 10.

Appending Items: You can add items to the end of the list with append(). For example, my_list.append(5) adds 5 to the list.

Inserting Items: You can insert an item at a specific index with insert(). For example, my_list.insert(1, 8) inserts 8 at index 1.

Removing Items: Items can be removed using methods like remove(), which removes the first occurrence of a specified item, or pop(), which removes the item at a specific index.

Slicing: Lists can be sliced to get a sublist. For example, my_list[1:3] gives a sublist from index 1 to 2 (excluding 3).

Concatenation and Repetition: You can concatenate lists with + and repeat lists using *. For example, my_list + [7, 8] adds two new elements to the list, and my_list * 2 duplicates the list.

List Comprehensions: This is a shorthand way to create or modify lists. For example, [x*2 for x in my_list] creates a new list with each element doubled.

  1. Provide a real-world scenario where a filtering algorithm might be applied. A real-world scenario for a filtering algorithm is email spam detection. In this case, a filtering algorithm is used to identify and sort out spam emails from regular emails. The algorithm might filter out emails containing certain keywords (like “free money” or “urgent”) or identify patterns such as an unusually large number of emails sent in a short time, which could indicate spam behavior. By filtering out these unwanted emails, users can avoid wasting time on irrelevant content.

  2. Discuss why analyzing the efficiency of filtering algorithms is important for software development. Analyzing the efficiency of filtering algorithms is crucial for several reasons:

Performance Optimization: Inefficient algorithms can slow down applications, especially when dealing with large datasets. In applications like search engines or email clients, filtering millions of items quickly is essential to provide a smooth user experience.

Resource Management: Efficient algorithms use fewer system resources (CPU, memory), which is important when working with large datasets or running on limited hardware, like mobile devices.

Scalability: As software scales (more data or more users), the efficiency of algorithms ensures that the system remains responsive. Inefficient algorithms might work for small datasets but fail as the data grows.

User Experience: If filtering operations take too long, users might experience delays, which could negatively impact the application’s usability and reputation. Analyzing efficiency helps ensure that filtering tasks complete quickly, maintaining a good user experience.

Cost Efficiency: In cloud computing or distributed systems, inefficient algorithms can lead to higher operational costs due to increased resource consumption. By optimizing algorithms, companies can reduce computational costs.

In summary, efficiency is key in filtering algorithms to ensure software runs smoothly, scales well, and meets user expectations.