this post was submitted on 25 Jun 2024
19 points (95.2% liked)

Python

6356 readers
3 users here now

Welcome to the Python community on the programming.dev Lemmy instance!

πŸ“… Events

PastNovember 2023

October 2023

July 2023

August 2023

September 2023

🐍 Python project:
πŸ’“ Python Community:
✨ Python Ecosystem:
🌌 Fediverse
Communities
Projects
Feeds

founded 1 year ago
MODERATORS
 

I'm new to programming a bit, and am learning python so I can learn flask, using the python crash course book. I was learning about list comprehension but it briefly talks about it. If I do

list[list.append(value) for value in range(1, 20)]

it doesn't work. Would this be some sort of recursive expression that is not possible?

top 13 comments
sorted by: hot top controversial new old
[–] [email protected] 1 points 4 months ago* (last edited 4 months ago)

Not quite!

Try:

mylist = [value for value in range(1,20)]

This says I want to make mylist be a list where each element of the list (called value here) comes from doing a for loop on range, given the parameters 1, and 20.

If you want to change how each element of this list is, you do it in the first bit on β€œvalue”

So you could do

mylist = [value*5 for value in range(1,20)] //5,10,15,…,95 (not 100, because ranges go up to the last item, not including it (non-inclusive))

Etc. Hope this makes sense!

Edit: MISSING CLOSING PARENTHESIS DOH

[–] [email protected] 5 points 4 months ago* (last edited 4 months ago)
  1. list.append returns None so what you've actually got is a list comprehension that generates a list containing the value None 19 times. (using functions with side effects, such as list.append, in list comprehensions are generally bad style so you should avoid this)
  2. The list[...] syntax retrieves elements from the list, which is not what you're trying to do here. (and it is actually invalid syntax in this case)
  3. You should generally avoid calling lists list, because list is already a builtin.

If you want to append the numbers 1 to 19 to a list as you're trying to do you can call the list.extend function with the list comprehension [value for value in range(1, 20)] as the argument. (Although in this case you can also just use the range directly.) To do it without list comprehensions you can simply loop over the range and repeatedly call the append function.

[–] [email protected] 7 points 4 months ago* (last edited 4 months ago)

List comprehensions return a new list. For the sake of code clarity, you probably shouldn't change a second list from within a list comprehension. If you're trying to concatenate two lists, you can do so in a second line:

a = list(range(10))
b = [ value for value in range(5) ]
a.extend(b)

# a has 15 elements
print(a)
[–] [email protected] 2 points 4 months ago (1 children)

List comprehension is not whatever you're doing there. An example of list comprehension:

list = [value*2 for value in range(1, 20)]

See, list comprehension is used to make a list from an existing list. The value of the new list is defined by a function. In this case, the value of a will be 2,4,6, etc.

Your current syntax list[...], is trying to access an element of a list.

[–] [email protected] 1 points 4 months ago (2 children)

So you cannot use methods inside a list comprehension, only binary operators and the function range?

[–] [email protected] 2 points 4 months ago* (last edited 4 months ago) (2 children)

You can. Whatever the method returns will be the element of that list. So if for example I do this:

def mul(x):
  return x*2

list = [mul(value) for value in range(1,20)]

It will have the same effect. But this:

def mul(x):
  return

list = [mul(value) for value in range(1,20)]

Will just makes the list element all None

Edit to add more: List comprehension works not from the range function. Rather, the range function is returning a list. Hence the name, "list comprehension". You can use any old list for it.

What it did under the hood is that it iterates each element on the list that you specify (the in ...), and applies those to the function that you specify in the very first place. If you are familiar with the concept of Array.map in other languages, this is that. There is also a technical explanation for it if it helps, but it requires more time to explain. Just let me know if you would like to know it.

[–] [email protected] 1 points 4 months ago* (last edited 4 months ago) (1 children)

I know I'm being somewhat pedantic but range() returns an iterable range type, not a list, in python 3.

[–] [email protected] 1 points 4 months ago

Not at all. It is indeed helpful to differentiate between an iterable and literal list. After all, sometimes it will bite you in the ass when you don't differentiate between the two.

[–] [email protected] 1 points 4 months ago (1 children)

Thanks for the response.

I am aware somewhat of what an array is, as i've dabbled with them in C, and know they can be multi-dimensional. Sorry if I'm being blind, but all I see are function calls in that list comprehension. I think what im asking is stupid, as the range function is returning a list populated.

[–] [email protected] 2 points 4 months ago* (last edited 4 months ago) (1 children)

No problems. Learning a new concept is not stupid. So you are familiar with C. In C term, you are likely to do something like this:

int a[10] = {0}; // Just imagine this is 0,1,2,etc...
int b[10] = {0};
for (int i=0; i < 10; i++) {
  b[i] = a[i]*2;
}

A 1 to 1 correspondent might looks like ths:

a = range(10) # 0,1,2,etc...
b = []
for x in a:
  b.append(x*2)

However in python, you can then simplify to this:

a = range(10) # Same as before, 0,1,2,etc...
b = [x*2 for x in a]

# This is also works
b = [x*2 for x in [0,1,2,...]]

Remember that list comprehension is used to make a new list, not just iteration. If you want to do something other than making a list from another list, it is better to use iteration. List comprehension is just "syntactic sugar" so to speak. The concept comes from functional programming paradigm.

[–] [email protected] 1 points 4 months ago

Great explanation! I don't know too much C, just a bit here and there, and my dad's copy of K&R C he gave to me.

[–] [email protected] 0 points 4 months ago

Sure you can. As others have said, a list comprehension returns a new list. See the documentation.

What are you trying to do though? Append a list comprehension to an existing list?

See a modified version of @[email protected]'s code from their comment.

def double(x):
  return 2 * x
a = list(range(10))
a.extend(double(value) for value in range(5))

# a has 15 elements
print(a)

Anti Commercial-AI license

[–] [email protected] 2 points 4 months ago

A list comprehension is used to convert and/or filter elements of another iterable, in your case a range but this could also be another list. So you can think of it as taking one list, filtering/converting each element and producing a new list as a result.

So there's no need to append to any list as that's implicit in the comprehension.

For example, to produce a list of all squares in a range you could do:

[x*x for x in range(10)]

This would automatically "append" each square to the resulting list, there's no need to do that yourself.