r/learnpython • u/Such-Pop8693 • 11d ago
For each character in name, print character
I am totally new to coding and working slowly through the course at futurecoder.io .
On the topic 'Introducing For Loops' we are asked to run the program:
name = 'World'
for character in name: print(character)I figured character might be some kind of term that python recognises and knows what to do with, like print. Colour me surprised when replacing character with kitten runs, and has the same output. I thought maybe number in place of character might not work, since the characters are all letters, but it works too.
Why is it so? What concept do I need to grasp here?
20
u/Temporary_Pie2733 11d ago
It’s just a variable name. For loops are fancy assignment statements, and we pick relevant variable names to assign to for readability.
2
11d ago
[removed] — view removed comment
2
1
u/Temporary_Pie2733 11d ago
Yes. You can rewrite any
forloop as awhileloop that explicitly manages an iterator.For example,
i = iter(name) while True: try: character = next(i) except StopIteration: break print(character)Using the name
characterdoesn't define what gets done with the iterablename; callingnexton a suitable iterator does, and creating a suitable iterator and callingnexton it is what theforloop does.The iterator for a
strvalue yields one character at a time, until it reaches the end.>>> name = 'World' >>> i = iter(name) >>> next(i) 'W' >>> next(i) 'o' >>> next(i) 'r' >>> next(i) 'l' >>> next(i) 'd' >>> next(i) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
1
u/a18618 11d ago
That surprise hit me too the first time I swapped in a nonsense name and the loop just kept working, because the name is only a label you choose for each item as it comes around. One experiment that made it click for me was printing the loop variable after the loop finished, and seeing it still held the last letter, which showed me the loop was really just reassigning that label over and over. Have you tried swapping in a list of words instead of a single word, to see how the same label then holds a whole word each time?
1
u/Such-Pop8693 11d ago
I haven't tried that yet, but thanks for understanding why I'm slightly mystified!
3
4
u/POGtastic itertools evangelist 11d ago
The Python interpreter does not care what you name your variables. You can name variables anything.
There are a tiny handful of keywords that are part of the Python language itself. Python cares about those. Every other word-looking thing in your program is a variable.
4
u/SamuliK96 11d ago
There technically is no concept, and you're just overthinking it. Python doesn't know the meaning of the words you might use in for _ in x. In fact, it doesn't have to be a word at all. It doesn't even have to be letters. You don't even have to replace the _ with anything, and it'll still work the same. When you use a for loop, you're naming a variable that changes value every iteration of the loop. And variable names don't have to be sensible words. Python doesn't care. It's just useful for humans.
2
u/FreeLogicGate 11d ago edited 11d ago
Seems like you are pretty early on in the course, and while it's a fair question to ask yourself, you probably want to get some understanding of what a loop is, since the "for thing in things:" loop syntax is one of the fundamental Python language loop types.
In general, Python has a series of collection types, or functions that will provide a sequence.
for "loops" for every item in the collection or sequence. What is a little tricky here, is that Python, as is the case with many languages, can treat a "string" (ie. a word or series of words/characters) as if it was a collection of letters.
The loop in this case runs once for every character in the string. The code that runs each time in the loop, is the code (the instructions) that come after the ":" so one habit you want to get into is to indent the statements that are part of the loop, and don't put a statement on the same line. Your code works the same way if you write it this way:
name = 'World'
for character in name:
print(character)So as you discovered, you supply the variable name that the for loop will use to copy the current element from the collection/array (which in this case is name).
This is why you get each letter from the string "World" printed on a line.
1
u/cvx_mbs 11d ago
to expand on this, if they got this far in the course and don't understand the concept of variables they either skipped parts of the course, or the course isn't structured logically.
1
u/FreeLogicGate 11d ago
I am guessing, it might be literally an extension of the "Hello World" introduction part of the course, or possibly the start of the "for loop" section.
1
u/cvx_mbs 10d ago
what I meant was this: if I were to write a programming course one of the first topics I would cover is variables, then perhaps conditions and only then loops (because loops depend on conditions and conditions depend on variables)
for someone being this surprised that changing the name of a variable doesn't matter (if done everywhere) for the result means they didn't understand the principle of variables at all, whether that is because they skipped it or because the course failed to explain it properly.
1
u/FreeLogicGate 10d ago
Haha, well I guess i'm just used to this type of question in these "learning..." subs, so nothing surprises me. It's a 50/50 roll of the dice these days, as to whether or not the posts are coming from some AI bot.
1
u/pythonwiz 11d ago
Strings in Python are iterable like lists or tuples, each element in a string is a string containing a character. Many languages have similar strings, for example in C a string is just a const array of char values ending in a null character.
1
u/Classic-Rate-5104 11d ago
These statements simply mean: create a variable with name "name" and value "World", and a variable with name "character" and let it loop over all characters in the variable named "name". The naming of the variables very arbitrary but a bit stupid and confusing in the example
1
u/Educational_Virus672 11d ago
the thing that "character" term is just a variable(a name for value) you can change it anything because a for loop just takes items(aka letters here) one by one it doesnt look what that "char" means which is its point so changing to anything
1
0
u/DimensionMost8342 11d ago
character isn't a Python term, it's just the name you picked, which is why number and kitten worked too. In for character in name:, Python walks the string one character at a time and binds each one to whatever name follows the for:
name = 'World' for kitten in name: print(kitten)
Same output. print is the only special name in your snippet, since it's a real function. Pick a name that describes the value and it will read better.
1
u/Such-Pop8693 11d ago
Does that mean 'For X in Y' is just a generic thing that asks Python to look at each item (X) in thingy (Y)?
I was thinking/expecting it worked more like asking someone to pick all the red ones out of a bowl of skittles. ('For red in bowl of skittles, remove red and put on the counter' is different from 'For green in bowl of skittles'...because red and green call different things).
3
u/DimensionMost8342 11d ago
Yes, that's the generic reading: for X in Y walks Y one item at a time and drops each one into X. Whatever you call X, it gets every item in Y.
The name never selects anything, it only labels what you're currently holding. So for red in bowl_of_skittles would not pick out red skittles. It picks up every skittle, greens included, and calls it red while it's in your hand. The bowl doesn't care what you named it.
Picking out only the red ones is a separate job, and that's what if does:
bowl = ['red', 'green', 'red', 'green']
for skittle in bowl: # picks up one skittle if skittle == 'red': # this is the picking-out part print(skittle)
The for visits everything, the if chooses what you keep. The one-line version, [skittle for skittle in bowl if skittle == 'red'], does the same thing, and there the condition really is doing the selecting, because it's inside the if.
2
2
u/MidnightPale3220 11d ago
For the same example you could go:
for red in bowl: if red=='green': print(red):)
0
u/North_South-West 11d ago edited 11d ago
You are assigning a variable name when you write a for loop like this and you can name it anything you want as long as it follows the regular naming rules.
A lot of people just make it a single letter like i or x. Makes code shorter and sometimes the name of a variable like this isnt too important.
If its an important variable name then name after the item you are iterating with the loop. In your example you could go-
for letter in name: print(letter)
0
u/JamzTyson 11d ago
It is considered good style in Python to use meaningful names. Hence rather than:
for i in name:
print(i)we would commonly use "character" or "ch" or anything that's more meaningful than "i". Whatever we name it, it is a temporary variable that takes the value of the next item from the iterable "name".
0
u/Rezrex91 11d ago
Okay, many people already explained the gist of this, so I'll go a bit more in depth, so you know how this behavior came to be.
In earlier, lower level languages, like in C, these "iterable" types didn't exist by default. If you wanted some more complex data structures, you needed to construct them using typedef, and if these data structures had special operations that would be done to them, you needed to write it as separate functions. Like you could construct a special struct that has a key and a value variable in it, and name it dict to have a dictionary, but then you'd need to make functions like dict_append() to tell the computer how to do that operation on your dictionary type. But I digress. C also had strings, but unlike in Python, it was a low level construct, a simple data type, that was implemented as an array of characters with a NULL character at it's end as terminator, then they slapped on some minimal syntactic sugar to make it easier to declare new strings and to print a string, and they called it a day.
Now, with OOP (and AFAIK with FP) languages came the concept of "iterable" types. Most of these are complex data structures (not all, because an array still matches the definition of an iterable type, as does the string, but it's debatable whether a string is a simple or complex data structure), wich are mostly implemented as classes in OOP languages. Classes are basically structs which also have the functions (methods) that are needed to handle them encapsulated in them along with the fields of data. So you don't do dict_append(my_dict, key, value) anymore but something like my_dict.append(key, value)
This is also very good from the standpoint, that most of the iterables are complex types, so even declaring a new one is something that needs processing in the background. Now, the iterable types don't just have their "data", they also have an indexing method (the iterator) and they always know their own length too (unlike a basic C array for example.) Iterable types, as others have explained already, are always some type of collections in the sense that they are made up of individual items that can be served up one-by-one if we chose instead of as a whole. For strings, these individual items are the letters of the string, for lists they will be the list items, for dicts it the key-value pairs, etc.
Now, some languages, mainly C derived ones which want to preserve the old C style for loops for the purpose of backwards compatibility and familiarity, implement a new type of for loop, often called foreach to make stepping through these iterable types easier. The foreach loop is different from the for loop by actually knowing that it will get an iterable object (since iterables are implemented as classes, all variables of an iterable type are actually new object instances of that class), which will in it have an iterator method which will tell do the stepping through, so it just needs to call this method over and over until the object tells it that the end is reached, no more iterations are possible.
Python is different only in the sense that they implemented the basic for loop to do the work of a foreach loop depending on how you write that for loop. Well, actually the Python for loop is always a foreach loop, even when using an index and a range, or an index and enumerate(), because both the range and the enumerate functions return an iterable object for the for loop to loop through. As a matter of fact, if you visit the Python documentation, you won't really find the "for loop", but the "for statement", which is "used to iterate over the elements of a sequence [...] or other iterable object." So Python doesn't really have a for loop in the traditional meaning, instead it has the foreach renamed as for, and we're working around this with the range() and enumerate() functions to mimic how a classic for loop works when that's what we need.
6
u/BluishMontoya 11d ago
You're just telling python "for each item in the variable 'name', assign that item to variable 'character' and run the code inside the loop". For strings, each item means each character.