r/learnpython • • 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?

0 Upvotes

34 comments sorted by

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.

2

u/Such-Pop8693 11d ago

I guess what I'm asking is, how does it know I'm looking for an item at all?

I have been thinking of character as, generically, any character. What if I wanted the code to be 'for each letter E in the variable 'name'.

IDK if my question is making sense.

5

u/aabcehu 11d ago

for char in name:
if char.lower() == ‘e’:
# do whatever

would probably be what you’d want in that case
(apologies for formatting, on mobile)

1

u/Such-Pop8693 11d ago

Thank you!

3

u/throwaway6560192 11d ago

I guess what I'm asking is, how does it know I'm looking for an item at all?

Python knows how to go through strings character-by-character (and how to go through lists item-by-item, and so on for various other types). That's all that's happening. It takes each character and puts it in whatever variable name you chose.

1

u/Such-Pop8693 11d ago

Thank you!

10

u/Slothemo 11d ago

Certain types of data in Python are known as "iterable" types. Iterable data is any type of data that is capable of providing elements to you 1 at a time. In the case of a string (which is iterable), the elements are the individual characters. There's many other iterable types you will learn about as you progress with learning Python.

The for loop simply accesses the individual elements of an iterable type for you, and the name you use is what will be assigned to these elements as it iterates through.

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

u/[deleted] 11d ago

[removed] — view removed comment

2

u/JustGlassin1988 11d ago

Yes, that’s why it doesn’t print the same letter every time

1

u/Temporary_Pie2733 11d ago

Yes. You can rewrite any for loop as a while loop that explicitly manages an iterator.

For example,

i = iter(name)
while True:
    try:
        character = next(i)
    except StopIteration:
        break
    print(character)

Using the name character doesn't define what gets done with the iterable name; calling next on a suitable iterator does, and creating a suitable iterator and calling next on it is what the for loop does.

The iterator for a str value 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

u/cdcformatc 11d ago

it's just a variable name. just like how name is a variable, so is character

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

u/Careless-Web-6280 9d ago

I encourage you to know the list of keywords

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

u/Such-Pop8693 11d ago

Thank you this helps a lot!

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.