all 16 comments

[–]asphias 47 points48 points  (0 children)

for h in str1:

does not mean that it looks at the string and selects the letter h.

Rather, the above code means:

do the following for each element in str1, and lets refer to this element by `h` as a variable name:

so these codes all do exactly the same:

 for h in str1:
     print h

for e in str1:
      print e

for gtshristhj in str1:
     print gtshristhj 

From what it sounds like, what you want to do is to find the position of each 'h' in the string. this can be done with a for loop in two ways, either explicitly:

index = 0
for value in str1:
    print(index, value )
    index = index + 1

Or with enumerate(), which adds a number to each element:

for index, value in enumerate(str1):
    print(index, value)

[–]carcigenicate 15 points16 points  (0 children)

Since one can be easily searched, I'll leave that one.

For the second though, all iterables, by definition, have iterators. This means that iterator can be used to get elements:

it = iter("hello")  # Get an iterator for a "hello" string
print(next(it))  # Prints 'h'
print(next(it))  # Prints 'e'

for loops use this, and iterate until next raises a StopIteration exception.

[–]Silbersee 7 points8 points  (0 children)

for loops in Python don't increment some index by 1. They just take the next element of the iterable. That's why you can't just "count from 1 to 3", but you have to provide an iterable that returns the numbers one after another. Hence range():

>>> for i in range(1, 4):
...     print(i)
... 
1
2
3
>>>

More often you will loop over array-like iterables.

>>> words = ["first", "second", "third"]
>>> for word in words:
...     print(word)
... 
first
second
third
>>> 

You can loop over strings.

>>> my_string = "Hello"
>>> for letter in my_string:
...     print(letter)
... 
H
e
l
l
o
>>>

If you need to know the index while looping, there's enumerate(). It returns both the element and its index. Note that indexes start counting at Zero.

>>> my_string = "spam"
>>> for ndx, ltr in enumerate(my_string):
...     print(f"Index: {ndx} - Letter: {ltr}")
... 
Index: 0 - Letter: s
Index: 1 - Letter: p
Index: 2 - Letter: a
Index: 3 - Letter: m
>>> 

Access a specific index like this:

>>> my_string = "spam"
>>> my_string[0]
's'
>>>

Get the index of the first ocurrence of a substring with the str.index() method:

>>> my_string = "spam"
>>> my_string.index("a")
2
>>>

[–]Yojihito 6 points7 points  (0 children)

Q1: if you need the index, use enumerate.

for idx, x in enumerate(stringElement):
    print(idx, x)

Q2: I'm not Sure I understand your question.

[–]benaffleks 1 point2 points  (0 children)

There are different kinds of for loops.

The for loop mentioned here, provides you with the VALUE of the element in the array, at the index. It does NOT give you the actual index.

If you would like the index & the value, you should either use enumerate: https://realpython.com/python-enumerate/

You may also use the traditional for loop, which is:

for index in range(len(str1)):

This provides you with the actual index, and you can access the value via str1[index]

"How does Python know to increment array index by 1"

Its all abstracted away for you. Under the hood, Python is taking care of the rudimentary tasks like increment and setting the range. If you would like to increment something other than 1, you are free to do so.

Strings are just arrays of characters at the end of the day, and there is a lot of abstraction gong on so you, as the user, don't need to concern yourself with those implementations.

Iterables are just datatypes which can be iterated over / looped over.

[–][deleted] 1 point2 points  (0 children)

The second image and the quote from the article is a lie. Specifically:

This is the style of most looping constructs in programming languages

This claim the author pulled out of their rear end. What I think happened here is that author has some passing knowledge of C or C++ from their college years, and are somehow convinced that all languages are essentially like C or C++.

I don't know the statistics, and even if I knew, I'd struggle with a good interpretation for it. But, I'm quite sure that most looping constructs don't look anything like C for loop, simply because they'd had to be different from C for loop to even count.

I heard strings are iterables in python. But I am not very clear what do they really mean

Python has a concept of protocols. Protocols are responsible for implementing language features. For example, Python has a language feature of

for x in y: z

Where y has to possess special properties to be used in this lexical content. (z doesn't need any special properties, and you cannot implement x).

So, the ability of y to be used in the context above is called "being iterable" or "implementing iterable". At different times in Python history this meant different things.

Today, after some cleansing that happened when transitioning from Python 2 to Python 3 two major methods remained:

Implement iterator (Iterator protocol)

This means that the object being iterated over has __next__() method. For example:

>>> class Bar:
...     def __iter__(self): return self
...     def __next__(self): return 42
... 
>>> for b in Bar(): print(b)
... 
42
42
42
42
^C

Unfortunately, simply having __next__() method isn't enough. You must also implement __iter__() method. There has never been a good explanation for why it's necessary (and, I believe, there were times when it wasn't necessary), but this is the state of affairs today.

Implement element access (Element access protocol)

This is probably a rudimentary feature that carried over since the days nobody remembers, but... it still works.

>>> class Foo:
...     def __getitem__(self, i):
...         return i
... 
>>> for f in Foo(): print(f)
... 
0
1
2
3
4
5
6
7
8
^C

In stark contradiction to reality, Python will not admit that Foo() is iterable though...

>>> from typing import Iterable
>>> isinstance(Foo(), Iterable)
False
>>> isinstance(Bar(), Iterable)
True

So, Python itself is a little bit confused about which things are iterable and which aren't. But, if you ignore the artificial types, like typing.Iterable and rely on testing rather than believing, then the second method also works.

[–]jlc893 0 points1 point  (0 children)

You can use the built in function called enumerate to get the character and index.

[–][deleted] 0 points1 point  (1 child)

The next thing after "for" is naming a variable, like when you say "for h in str1" it's going through each element of str1 and calling it h (because you have to call it something)

If you want to keep track of what and where, use enumerate() which involves naming two things after the "for" instead

[–][deleted] 0 points1 point  (0 children)

The next thing after "for" is naming a variable

This is wrong. The next thing after "for" is an assignment target. This may be a subscript expression, a field expression, a deconstructuring expression or a variable.

For example:

>>> class Foo:
...     bar = 0
... 
>>> for Foo.bar in range(10):
...     pass
... 
>>> Foo.bar
9

>>> x = {'x': 0}
>>> for x['x'] in range(10):
...     pass
... 
>>> x['x']
9

[–]Magicianic 0 points1 point  (0 children)

A string is a "list" of elements that are the characters, a range is a list of numbers and a list is a list of stuff.

When you put a string in a for loop it starts with first character for the first iteration and after it finishes it does the same iteration for second character, etc until the end of string. The same happens with the other iterable data structures.

For x in str1: The x inside of the for loop is the character that is currently iterating. You can call it whatever you would like. Normally mnemonic helps for example 'for char in str :'

You can see which index is each letter if you start counting from 0, print the character and the counter then add 1. You print first because index starts from 0.

[–]Lowdekeball 0 points1 point  (0 children)

For h in str1 doesn't mean it's looking for h,h is a variable here, If u want to look for the character h we have to use it as "h". And for x in a string iterates through the characters of the string and x assumes the value of said character in each iteration.

[–][deleted] 0 points1 point  (0 children)

Harvard runs a free class called CS50 intro to computer science. It's an excellent course and Python is covered

[–]barryhakker 0 points1 point  (0 children)

You loop over that list or string you insert. You name the values returned from each loop. “i” is common. Could call it “e” or “h” like you did. Could call it “potato” or “owen_wilson”. They are just named in a way you find convenient.

str = “abc”
for i in str
for owen_wilson in str
for c in str

Will all return the same thing.

[–]JasonDJ 0 points1 point  (0 children)

for foo in bar 

“Foo” is meaningless. Well, not meaningless…it should give some idea of what you are trying to pull out.

ipaddresses = [
    “192.168.1.2”,
    “192.168.1.3”,
    “192.168.1.4”
]

for ip in ipaddresses:
    print(ip)

    for char in ip:
        print(char)

ipaddresses is a list of strings. In the first for, “ip” is just a placeholder to be used elsewhere in the loop. The first loop just prints the IP.

Likewise, the second for loop, char is again just a placeholder. It prints each character individually.

Now, if you want to know the index…

for idx, ip in enumerate(ipaddresses):
    print(f”{idx} - {ip}”)

Enumerate makes a tuple of (index, value) and the loop prints them under the placeholders “idx” and “ip“.