Solved

Need some help with list manipulation in a Loop

Posted on 2015-01-18
13
128 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
Comment Utility
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
Comment Utility
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
Comment Utility
@Smyken

Will you need to repeat this process to move multiple 1 values to multiple zero values?
0
 
LVL 16

Expert Comment

by:gelonida
Comment Utility
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
Comment Utility
@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
Comment Utility
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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Author Comment

by:Smyken
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
@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
Comment Utility
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
Comment Utility
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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
This is about my first experience with programming Arduino.
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

763 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

10 Experts available now in Live!

Get 1:1 Help Now