Solved

Need some help with list manipulation in a Loop

Posted on 2015-01-18
13
162 Views
Last Modified: 2015-01-20
I have a simple loop that manipulates a list.
My code below simply looks for nr 1 and any 0's that are present.
All the 0's are put in a new list and the index containing 1 is changed to 0.
From the zerolist I then randomly change a 0 to 1.

I need to alter my code below a little so it does this:
Finds element/nr 1 then look for where 0 elements are and move my nr/element 1 to next available 0 .
Simply put: I need to move my nr to the next available 0.
If nr 1 is last in list [2,0,0,2,1] then the first index containing the 0 should be changed to 1 [2,1,0,2,0]

The list will always consist of 5 elements just like in the example below.
List will maximum contain one nr 1.

         
examplelist = [0,2,1,0,0]
            zerolist = []
            for i, j in enumerate(examplelist):
                if j == 0:
                   zerolist.append(i)
                elif j == 1:
                   examplelist[i]=0
                shuffle(zerolist)
            if zerolist:
                examplelist[zerolist[0]]=1

Open in new window


Any help would be appreciated !
0
Comment
Question by:Smyken
  • 6
  • 4
  • 3
13 Comments
 
LVL 16

Expert Comment

by:gelonida
ID: 40557496
I'm not 100% sure I understood the question,  but I'll give it a shot:

To get a list of indices where a 0 value is located:
zeropos = [ idx for idx, val in enumerate(examplelist) if val == 0 
# result is [0, 3, 4]

Open in new window


If you know that  a list contains a certain element, then you can find it's position with index()
example:
examplelist = [0,2,1,0,0]
examplelist.index(1)
>>> 2

Open in new window


so to set the value to 0:
examplelist[examplelist.index(1)] = 0

Open in new window


having the list zeropos and using the module random you can now randomly set one of these positions to 1:

import random
# get a random choize out of the positions containing zero
pos_to_change = random.choice(zerpos)

# now set this value to 1
examplelist[pos_to_change] = 1

Open in new window


Complete solution (if I understood well):
import random

def find_one_and_move_to_a_zero(alist):
    """ function moving a 1 value to a random zero value of the list """
    # find 1 position
    one_pos = alist.index(1)

    # find 0 positions
    zero_pos_lst = [ idx for idx, val in enumerate(alist) if val == 0 ]

    # clear 1
    alist[one_pos] = 0

    # determine random 0 entry
    chosen_zero_pos = random.choice(zero_pos_lst)

    # set one value
    alist[chosen_zero_pos] = 1

example_list =  [2,0,0,2,1] 
print("Before %r" % example_list)
find_one_and_move_to_a_zero(example_list)
print("After %r" % example_list)

Open in new window


Attention. The given solution will change the list. If you want to keep the original list unmodified, then this is also possible with two minor modifications. the function has to create a copy of the initial list and return it as result. If this is required I can show you
0
 
LVL 16

Expert Comment

by:gelonida
ID: 40557531
Oops I accidentally just rewrote your initial code. So if you want to move the 1 to the first available 0 position, then use following function:

#!/usr/bin/env python

import random

def find_one_and_move_to_a_zero(alist):
    """ function moving a 1 value to a randmo zero value of the list """
    # find 1 position. No error checking. There MUST be a 1 in alist
    one_pos = alist.index(1)

    # set 1 to 0  # move next line to end of function if you want to move
    # the 1 to the next 0 if the one was on a position left of the first 0
    alist[one_pos] = 0

    # find first 0 position. 
    zero_pos = alist.index(0)
    alist[zero_pos] = 1
    

example_list =  [2,0,0,2,1] 
print("Before %r" % example_list)
find_one_and_move_to_a_zero(example_list)
print("After %r" % example_list)

Open in new window

0
 
LVL 45

Expert Comment

by:aikimark
ID: 40557879
@Smyken

Will you need to repeat this process to move multiple 1 values to multiple zero values?
0
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 
LVL 16

Expert Comment

by:gelonida
ID: 40558090
The way I wrote the code it will only handle the first 1 it finds. This is what you asked for.
If you need something else, then try to give me a good example.  
It should not be difficult to code it, but I'd like to be sure that the code will do exactly what you want.
0
 
LVL 1

Author Comment

by:Smyken
ID: 40558672
@aikimark
No there will only be just 1 nr 1 and it needs to be moved to next available 0.

@gelonida

Your solution partially worked.
if my examplelist is
[0,1,0,2,0] 

Open in new window

then the processed list should look like this:
[0,0,1,2,0] 

Open in new window

My item 1 must always move forward to the next available 0 but your solution seems to pick first available 0 and show the list like this:
[1,0,0,2,0] 

Open in new window


I actually managed to get it working but I'm just a newbie to programming and I think that there should be a way better method to do this:

examplelist = [0,0,1,0,0]
print examplelist

zero1 = []
zero2 = []
for i, j in enumerate(examplelist):
    if j == 1:
        x = i

for i, j in enumerate(examplelist):
    if i > x and j == 0:
        zero1.append(i)

for i, j in enumerate(examplelist):
    if i < x and j == 0:
        zero2.append(i)

if zero1:
    examplelist[zero1[0]]=1
    examplelist[x]=0
elif zero2:
    examplelist[zero2[0]]=1
    examplelist[x]=0

print examplelist

Open in new window

0
 
LVL 45

Expert Comment

by:aikimark
ID: 40558691
you've changed the requirement.  You originally stated that the first available 0 was the swap partner with the 1.  Now you seem to be saying it is the next 0 position AFTER the 1, wrapping around to the beginning of the list.
0
 
LVL 1

Author Comment

by:Smyken
ID: 40558737
Sorry if I was unclear kind of hard to explain, but I wrote in bold in description that it was Next 0 not first.
Anyhow sorry for being unclear.
0
 
LVL 45

Expert Comment

by:aikimark
ID: 40559052
What if there is no next zero?
What if there is no zero?
What if there is no one?
0
 
LVL 45

Expert Comment

by:aikimark
ID: 40559059
This would seem like the simplest swap for the case when there is a zero after the one:
a=[2,1,0,2,0]
oneposn=a.index(1)
nextzeroposn=a[oneposn+1:].index(0)
a[nextzeroposn+oneposn+1], a[oneposn] = 1,0
a
[2, 0, 1, 2, 0]

Open in new window

0
 
LVL 45

Accepted Solution

by:
aikimark earned 400 total points
ID: 40559079
This snippet handles zeroes to the right or left conditions.
a=[2,0,0,2,1]
#a=[2,1,0,2,0]
if 1 in a and 0 in a:
	oneposn=a.index(1)
	try:
		nextzeroposn=a[oneposn+1:].index(0)+oneposn+1
	except:
		nextzeroposn=a[:oneposn].index(0)

	a[nextzeroposn], a[oneposn] = 1,0

Open in new window


Of course, this code would probably be packaged in a function.
0
 
LVL 16

Assisted Solution

by:gelonida
gelonida earned 100 total points
ID: 40559208
@aikimark: I agree question was phrased a little ambigiously if both of us got it wrong. I saw that the question is now changed to be less ambigious

@smyken: It's really best to give examples of a normal case and all special cases.
In your example this would have been having a 1 just moving to the first 0 right of it and one special case for a one having to move to the first 0 of the list as there's no more right of it.
It's also very important to know whether it can happen, that there is no 0 at all in the list.
If I understood you said there will be maximum one 1,

So does it mean, that there can be no 1 at all and that it is possible to have no 0 values?
What was good and important was, that you mentioned, that the list is short and has only 5 elements. Ths helps to understand, that you do not need a fast, optimized high performance solution.

aikimark's solution seems to fulfill the requirements you have. It would not be optimal for large lists list, but for length 5 the code should be perfect as it is simple and rather easy to understand.

From a Python point of view there's three interesting things in aikamark's code which you could look at:
1.)
if 1 in a  # allows to search in a list for a given element if a is a list,
    # or for a sub string if a is a string or for a key if a is a dict

2.)
a[pos:]  # this is array slicing look at https://docs.python.org/2/tutorial/introduction.html and search for slicing

3.) the try and except keyword # this is python exception handling refer to https://docs.python.org/2/tutorial/errors.html
0
 
LVL 1

Author Comment

by:Smyken
ID: 40559873
Thanks guys !
You have been both very helpful.
Next time I will try to write my Questions in a better manner.
0
 
LVL 45

Expert Comment

by:aikimark
ID: 40560702
You can also use the second parameter of the Index() method to specify the starting position for the search.
Example:
a=[2,0,0,2,1]
#a=[2,1,0,2,0]
if 1 in a and 0 in a:
	oneposn=a.index(1)
	try:
		nextzeroposn=a.index(0,oneposn+1)
	except:
		nextzeroposn=a[:oneposn].index(0)

	a[nextzeroposn], a[oneposn] = 1,0

Open in new window

0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
topping3 challenge 14 78
silent install of security banner via msiexec command 4 86
Path to Python 9 118
Advice on Xojo as a development tool over VB. 4 52
This is an explanation of a simple data model to help parse a JSON feed
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
Learn the basics of strings in Python: declaration, operations, indices, and slicing. Strings are declared with quotations; for example: s = "string": Strings are immutable.: Strings may be concatenated or multiplied using the addition and multiplic…
Learn the basics of while and for loops in Python.  while loops are used for testing while, or until, a condition is met: The structure of a while loop is as follows:     while <condition>:         do something         repeate: The break statement m…

816 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now