Reputation: 59
I'm studying how to use for loops and so on and I'm trying to come up with a way to make a string of similar characters sort itself so that no characters are repeated
# string of characters
chars = 'abbbababa'
# my idea was to make it an enumerated string
charsnum = enumerate(chars)
# while doing that I discovered the following
chars = 'babbbaba'
for i in charsnum:
for j in charsnum:
for z in charsnum:
for k in charsnum:
print(i,j,z,k)
# each time I add a loop the string becomes shorter
(0, 'b') (1, 'a') (2, 'b') (3, 'b')
(0, 'b') (1, 'a') (2, 'b') (4, 'b')
(0, 'b') (1, 'a') (2, 'b') (5, 'a')
(0, 'b') (1, 'a') (2, 'b') (6, 'b')
(0, 'b') (1, 'a') (2, 'b') (7, 'a')
I know that the first loop iterates through all the values in charsnum, but what are the second, third, and so on for loops iterating through? Also, what could be a good solution to making my string 'babbbaba' in to a string like 'bababababa' or 'ababababa' where no values repeat.
Upvotes: 0
Views: 698
Reputation:
Your question and example are really confusing, I think this is what you are looking for.
A way easier way to do this is to use a list comprehension, which will iterate through your set of characters in a more compact, pythonic manner.
chars = 'abbbababa'
print( [i for i in chars] )
Result:
a
b
b
b
a
b
a
b
Now you can iterate over your indices to check if they are equal to the previous.
win = [i for i in chars] # Convert chars string to a list of chars
last = '' # Create a variable to hold our last result
for i in win:
if i != last:
print(i)
last = i # Set last to equal the last char iterated
Result:
a
b
a
b
a
b
a
Or if you want to print them out in a single string...
win = [i for i in chars] # Convert chars string to a list of chars
last = '' # Create a variable to hold our last result
newchars = ''
for i in win:
if i != last:
newchars += i
last = i # Set last to equal the last char iterated
print(newchars)
Result
abababa
Upvotes: 0
Reputation: 1121486
You are asking several for
loops to all iterate over the same, single iterator. You did not create copies, they share one object.
The outer loop advances the charsnum
object by one step, then the next for
loop advances it once to start its iteration, and so on. The innermost for
loop takes the remaining items to iterate over, and by the time you go back up to the for z
loop there is nothing left to iterate over.
You can do the same thing, advancing the iterator like for
does, with the next()
function:
>>> chars = 'abbbababa'
>>> charsnum = enumerate(chars)
>>> i = next(charsnum)
>>> j = next(charsnum)
>>> z = next(charsnum)
>>> k = next(charsnum)
>>> i, j, z, k
((0, 'a'), (1, 'b'), (2, 'b'), (3, 'b'))
>>> next(charsnum) # next k value in the innermost loop
(4, 'a')
>>> # etc. etc.
You could create separate enumerate()
objects for each for
loop:
for i in enumerate(chars):
for j in enumerate(chars):
for z in enumerate(chars):
for k in enumerate(chars):
print(i,j,z,k)
but that's just more work than you need. For nested loops repeating the same iterable, use itertools.product()
and tell it to repeat; it'll keep copies as needed:
from itertools import product
for i, j, z, k in product(enumerate(chars), repeat=4):
print(i, j, z, k)
This won't eliminate repeated characters, however; this produces the cartesian product of 4 (index, char)
tuples out of all possible such tuples from your char
string.
You probably want to create permutations form the unique letters, and string out the patterns those make into something the same length:
from itertools import permutations
for pattern in permutations(set(chars)):
repeat = (len(chars) + 1) // len(pattern)
result = (''.join(pattern) * repeat)[:len(chars)]
print(result)
This produces
babababab
ababababa
Upvotes: 4
Reputation: 744
The "problem" is not at the for
loops, but at charsnum
. The object charsnum
is a generator that yelds the next value everytime it is called.
In the first for
loop (for j in charsnum
) it yelds the first item in chars
but in the inner loop (for z in charsnum
) charsnum
will yeld the next item in chars
. So this inner loop will never access the first item in chars
.
Upvotes: 0