I recommend against using the file readlines method in #Python.

Many folks assume that readlines returns a lazy iterable (an iterator) of lines. But the readlines method returns a list, not an iterator!

These are equivalent:

lines = my_file.readlines()
lines = list(my_file)
If you need to lazily loop over lines in a file, you can loop over the file object itself to do that:

for line in my_file:
...

You can use a file like any other iterable. For example you can use it in a comprehension:

non_empty = [line for line in my_file if line.strip()]
When I need to make a list of all lines in a file, I use the list constructor:

lines = list(my_file)

I find that clearer than this:

lines = my_file.readlines()

☝ That second line can lead newer Pythonistas to assume this is okay:

for line in my_file.readlines():
...
Just a reminder that you shouldn't do this:

for line in my_file.readlines():
...

That unnecessarily makes a list of all lines that gets deleted after the loop.

This does NOT store the whole file in memory, but loops over lines lazily instead:

for line in my_file:
...
More on reading files line-by-line in Python: pym.dev/reading-files-…

More on iterables in Python: pym.dev/terms/#iterable

Python Morsels subscribers can watch my whole series on working with files here: pym.dev/topics/playlis…

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Trey Hunner (Python trainer)

Trey Hunner (Python trainer) Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @treyhunner

May 26
Python's "for" loops are single-purposed: they can loop over an iterable item-by-item. That's it.

The "for" loop itself can't loop in reverse or loop over multiple iterables.

For this reason, looping helpers are a VERY big deal in #Python.

Let's talk about looping helpers. 🧵
Want to loop over an iterable in the reverse direction? If it's a reversible iterable (lists, tuples, dictionaries, etc), you can use the reversed helper:

>>> colors = ["pink", "blue", "green"]
>>> for color in reversed(colors):
... print(color)
...
green
blue
pink
Note that the "for" loop isn't reversing here: reversed is!

The built-in reversed function accepts an iterable and returns a lazy iterable that provides each item from the original iterable in the reverse order.

>>> r = reversed(colors)
>>> next(r)
'green'
>>> next(r)
'blue'
Read 12 tweets
May 24
Ever wondered "what's a float"?

floating point number (a.k.a. float): an object used for representing real numbers using a fairly accurate approximation

Let's talk about floats work in #Python!

#TerminologyTuesday
Floating point numbers are an approximation of their decimal equivalents.

They're super useful for most uses, but they can't be relied on for exact precision.

You can't assume that an exact equality comparison with floating point numbers will work:

>>> 0.1 + 0.02 == 0.12
False
Adding 0.1 and 0.02 results in a number that is VERY slightly different from the 0.12 number that we'd expect:

>>> 0.1 + 0.02
0.12000000000000001

This might seem like a huge problem, but it's usually not! This imprecision typically only causes trouble with strict equality.
Read 11 tweets
May 19
I love Python's pathlib module. 💖🐍🗃

Whenever I need to ask a question about a file path in #Python, I default to using pathlib.

Let's talk about some of my most common uses for pathlib and compare them to their non-pathlib alternatives. 🧵
Assume all the below examples include the "filename" and "path" variables defined like this:

>>> from pathlib import Path
>>> filename = "my_file.txt"
>>> path = Path(filename)

Also assume that we've imported os, glob, and os.path as needed:

>>> import glob, os, os.path
Get an absolute path (from a path that may be relative or may already be absolute).

💾 Old approach:

>>> filename = os.path.abspath(filename)

✨ pathlib approach:

>>> path = path.resolve()
Read 12 tweets
May 17
Here's a deceptively fuzzy #Python term: mutable object. 🤔

mutable object: an object whose "value" can change

But what does "value" really mean?

#TerminologyTuesday
Lists are mutable because a list object can be changed.

>>> numbers = [2, 1, 3]
>>> numbers.append(4)
>>> numbers
[2, 1, 3, 4]

If two variables refer to the same list, any change to the list will be reflected by both variables:

>>> x = numbers
>>> x.clear()
>>> numbers
[]
Strings are immutable in #Python. That means that there is no way to "change" a string object in Python.

Try as hard as you might, you cannot change strings. You can only make NEW strings.

name = "Trey"
name = name + "!" # makes a new string
name += "!" # same as above
Read 12 tweets
May 9
Need to flatten a list-of-lists (or an iterable-of-iterables) in #Python?

There are about 5 "right" ways to do it and one "wrong" way (for some values of right and wrong). Which way you choose depends on your preference.
You may reach for nested loops:

names = []
for group in groups:
for name in group:
names.append(name)

But the extend method can replace the inner loop:

names = []
for group in groups:
names.extend(group)

If you prefer, += works as well:

names += group
I prefer to replace that for-for-append pattern with a comprehension:

names = [
name
for group in groups
for name in group
]

I find 2-loop comprehensions readable as long as each "for" component is on its own line of code. Whitespace is your friend! 💓
Read 7 tweets
Feb 14
Strings in #Python have a ton of methods on them.

I recommend learning these 10 first:

• join
• split
• replace
• format
• startswith
• endswith
• strip
• casefold
• splitlines
• count

Let's talk about what these methods do and why I recommend these ones first. 🧵
1️⃣ The string join method accepts an iterable of strings to join together.

It should be called on the separator you'd like to join by (e.g. " ", "\n", ",", ""). This is a string method: it's " ".join(my_list) and not my_list.join(" ").

2️⃣ The string split method is the opposite of join.

split accepts an optional separator:

time = "02:27"
h, m = time.split(":")

The default separator is "any consecutive whitespace characters".

Splitting can also be limited with a maxsplit arg.

Read 19 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(