0

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???

1
  • It would help if the answers actually explained HOW the for-loops work, rather than giving examples without explaining what each part does Commented Mar 17, 2012 at 12:44

6 Answers 6

3

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)]
Sign up to request clarification or add additional context in comments.

1 Comment

This should be at the top. However, there is no builtin xor function; you need pair[0] ^ pair[1].
1

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.

Comments

1

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 ) ]

4 Comments

You can't replace range( i, len( a ) ) with range( i ) as they aren't equal. range( i ) gives [0..i-1] and range( i, len( a ) ) gives [i..len(a)-1].
I agree that range( i, len(a) ) != range( i ) but, both for-loops cover the same range of elements. Mine covers i, j for all j < i, while the others covers for all i < j.
newbies in python wont understand this
im sorry that you didn't understand it
1

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.

Comments

0

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))

Comments

0

This nested Python loop should solve your problem.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.