Jump to content

Breaking out of double loop > constructing double loop into one


Recommended Posts

Posted

Hi there, hope you are all doing well in the current Corona situation!
My code: 

Array = [5,2,3,3,4,6,8]

for i in range(len(Array)):
	for j in range(i+1,len(Array)):
		if i != j and Array[i] == Array[j]:
			print('found one: ', Array[i])

I am still working my way through a python book and a question came up that had me identify duplicates within an array. Above is the solution which I came up with and it works. But I wanted to break out of both loops, because a previous iteration of this code produced each variable twice (I did not have the i+1 part). Now I found several solutions here: https://nedbatchelder.com/blog/201608/breaking_out_of_two_loops.html

And one thing the writer proposes is the construction of a single loop (he actually just hides the double loops into a a function and then calls that function later). This made me wonder if it is possible to construct my program, containing two loops, into a single loop. I tried some variations of:

for i, j in range(len(Array)):

But have not been able to find a way to make this work. My question: is there a way to do this, or should I just stick with the double loop?

Thanks for reading and stay Corona-free!
-Dagl

Posted (edited)

You could find math equation which is giving total number of internal loop executions and then use modulo or so to extract i and j variables from it.

e.g. (just an example pseudocode)

If we have loops like 

for i=0 to 10

for j=0 to 10

it is easy to figure out total number of internal loop executions.  It is 10 × 10 = 100

so we can write

for k=0 to 100

i=k/10 j=k%10

and instead of two loops there is just one..

 

 

Your code could be replaced by sort of array then two fields with the same value will be one after another. One loop goes through the all fields and internal if for checking two array entries to check whether they are equal or not.

 

Edited by Sensei
Posted
45 minutes ago, Dagl1 said:

My question: is there a way to do this, or should I just stick with the double loop?

Not sure this answers your question but a common construct in some program development is to use recursion*. Here is quick hack that produces the same result** as your code, without explicitly using loops:

Array = [5,2,3,3,4,6,8]

def recursive_Dagl1(i):
  if i==len(Array)-1:
    return
  try:
    if Array.index(Array[i],i+1):
      print('found one: ', Array[i])
  except ValueError: pass
  finally: 
    recursive_Dagl1(i+1)
    return

recursive_Dagl1(0)

 

*) https://en.wikipedia.org/wiki/Recursion_(computer_science)

**) Disclaimer: I've tried to quickly rewrite OP's code as recursive, not tried to create an efficient way to solve the task to find duplicates.

 

Posted (edited)

@Sensei
Thanks for your answer (Domo Arigato Sensei;p)  !! I was typing out that I didn't understand your answer, but I think writing out what I didn't get got me to understand what you said (I hope):

Array = [5,2,3,3,4,6,8] # I should of course program the expansion but because I just want to understand this part right now, I copied it 7 times
NewArray = [5,2,3,3,4,6,8,5,2,3,3,4,6,8,5,2,3,3,4,6,8,5,2,3,3,4,6,8,5,2,3,3,4,6,8,5,2,3,3,4,6,8,5,2,3,3,4,6,8] 
for k in range(len(NewArray)):
	i = k/(math.sqrt(len(Array)))
	j = k%(math.sqrt(len(Array)))
	if i == j:
		print('found one')

I think this works as intended (I hope this is what you meant), thank you very much

One more question is; does it make sense to do this, or just use that initial double-loop? 

@Ghideon

I am not yet at recursion in my programming book (although I have watched videos about it before;p) I will have to take a closer look at the code you posted to understand it, but thank you very much as well!

-Dagl

Edited by Dagl1
@link didn't work for Ghideon
Posted (edited)

@Dagl1

I and j are loop counters used as indexes to array. You need to compare array values instead of indexes.

 

You need to find math equation giving f(x)=1+2+3+....n. It will be total internal loop executions.

 

Use debugger to see what CPU is doing. It will help you understand issues.

Edited by Sensei
Posted (edited)
20 minutes ago, Sensei said:

@Dagl1

I and j are loop counters used as indexes to array. You need to compare fields values instead.

Oh f*ck, hahahaha how stupid.... I was so happy that it gave one answer, that I didn't think of it.

But now I will have to reassess it, because i (k/7) will be an non-integer (which I can make into an int, but that seems to produce a wrong answer. I will take a look at it for a while before asking again, thanks for the help and the comment catching my mistake!

Edit: Spotting quite a few mistakes in my quickly response to your answer, so I have some work ahead of me

Edited by Dagl1
Posted
47 minutes ago, Dagl1 said:

Edit: Spotting quite a few mistakes in my quickly response to your answer, so I have some work ahead of me

Don't we all???

Posted

Just an update, got part of it working, but stumbled upon another problem;/

Array = [5,2,3,3,4,6,8]
Length = len(Array)
for k in range(int(math.pow(len(Array),2))):
	i = k//Length
	j = k%Length
	# print(i,j)
	if Array[int(i)] == Array[int(j)] and j!=i:
		print('found one')

This is what I got, and it finds duplicates, it just finds them twice. In my original code I fixed that by letting the second loop only iterate from i+1, however I am at a loss if that is possible here (knowing the possibilities of coding, I am pretty sure it is possible, but I haven't been able to figure it out).
So I know there are a total of (don't know how to do Sigma summation here): (7-1)Sig(n)ma(i=1) = 21 internal loop iterations. Is this correct or not what you meant @Sensei?

Using 21 iterations I get something like this (I put in 21 myself but I suppose that defining a sigma function isn't difficult (or Numpy has one)):

Array = [5,2,3,3,4,6,8]
Length = len(Array)
for k in range(21):
	i = k//Length 
	j = k%Length
	print(i,j)
	if Array[-int(i)] == Array[-int(j)] and j!=i:
		print('found one')

the issue now being that i only reaches from 0 to 2, and j is still repeating 0 to 6. Could you give me a hint (doesn't have to be the full answer)?

Thanks and have a nice day!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.