Malice
Malice

Reputation: 1482

Nested for loop in python

I'm trying to learn the python scripting . Being some body who started coding in c/c++ or java i'm finding it extremely hard to find ways to write loops in python , especially for loops with conditions

I've a list A of string, i need to do a specific op on these strings a pair at a time ,say xor of the strings Also xor(a,b)=xor(b,a), hence i need to remove the redundant pair while looping

In traditional lang i would do something like

for(i=0;i<len;i++){
    for(j=i+1;j<len;j++){
        res[count]=xor(a[i],a[j])
        count++;
    }
}

So how do I implement the same with Python, I could think of iterators but is there a more efficient way , something very obvious eluding my eyes???

Upvotes: 0

Views: 1016

Answers (6)

Akshansh Rawat
Akshansh Rawat

Reputation: 11

It is quite easy,

Nested loops means there are multiple loops. Always remember that outer loop control the repeatation of inner loop.

for letter in [ 'a', 'b'] :
 for num in [1,2,3]:
       print(letter, num)

Output will be like - a1, a2, a3, b1, b2, b3

You can see that each element of outer loop engages with each element of inner loop. Thats what nested loop does.

Upvotes: 1

sulabh
sulabh

Reputation: 1117

This nested Python loop should solve your problem.

for i in range(len(a)):
    for j in range(i+1,len(a)):
        #do stuff

Upvotes: 0

Doboy
Doboy

Reputation: 11122

Here is another translation:

res = []
for i in range( len( a ) ):
    for j in range( i + 1 ):
        res.append( a[i] ^ a[j] )

or even this one liner

res = [ a[i] ^ a[j] for i in range( len( a ) ) for j in range( i ) ]

Upvotes: 1

jsbueno
jsbueno

Reputation: 110696

As you can see - there are plenty ways of doing it - using functions in the itertools module or rewritng then as lit comprehensions. Those, however, although nice, reduce readbility over conscision, and since you are starting now in Python, one important thing is to learn to think in "for" loops the Python way.

And the Python way fo for loops is: You don't iterate over indexes - you have sequences, and you want to perform actions for each element on a sequence - in C (and its derivatives) one does that indirectly by calculating the string length, iterating numbeers from 0 to the string lenght, an dusing those numbers as indexes on the string. In Python, the string is a sequence - you just use it as the element you want to interact on.

Apart from for loops, in Python, string items are substrings of len(1), not numbers on the 0-255 range, so you have to explicitly convert those to integers, perform the xor operation, and back - this canbe written as a one line lambda function such as :

xor = lambda c1, c2: chr(ord(c1) ^ ord(c2))

Alternatively, you can use "bytearray" objects that mimic strign, but behave somewhat like c strigns in a sense they are mutable, and its elements are treated as numbers in the 0-255 range.

As for your code:

res = ""
for position, char1 in enumerate(a):
    for char2 in a[position + 1:]:
        res += xor(char1, char2)

The "enumerate" call gives one the position of the element we are interating along with the element itself for cases like this.

Upvotes: 1

georg
georg

Reputation: 215039

Python comes with batteries included, that is, most of the stuff like this is already written for you. If you want combinations of strings, there is a dedicated function for that:

import itertools

result = []
for pair in itertools.combinations(a, 2):
    result.append(xor(pair[0], pair[1]))

or simply:

 result = [xor(*p) for p in itertools.combinations(a, 2)]

Upvotes: 3

Keith
Keith

Reputation: 43064

In python you often don't need loops like that because Python has implied loops as part of sequence operators such as slicing and list comprehensions. Also, you should not mutate a list while iterating over it so you just create a new list.

def xor(s1, s2):
    return "".join([chr(ord(a)^ord(b)) for a,b in zip(s1, s2)])

a = ["ab", "ba", "ab", "ba", "ab", "ba", "ab", "ba", "ab", "ba", "ab", "ba"]

res = [xor(a,b) for a,b in zip(a[::2], a[1::2])]
print(repr(res))

Upvotes: 0

Related Questions