40

I want to toggle between two values in Python, that is, between 0 and 1.

For example, when I run a function the first time, it yields the number 0. Next time, it yields 1. Third time it's back to zero, and so on.

Sorry if this doesn't make sense, but does anyone know a way to do this?

martineau
  • 119,623
  • 25
  • 170
  • 301
Yngve
  • 743
  • 4
  • 10
  • 15

14 Answers14

62

Use itertools.cycle():

from itertools import cycle
myIterator = cycle(range(2))

myIterator.next()   # or next(myIterator) which works in Python 3.x. Yields 0
myIterator.next()   # or next(myIterator) which works in Python 3.x. Yields 1
# etc.

Note that if you need a more complicated cycle than [0, 1], this solution becomes much more attractive than the other ones posted here...

from itertools import cycle
mySmallSquareIterator = cycle(i*i for i in range(10))
# Will yield 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 0, 1, 4, ...
martineau
  • 119,623
  • 25
  • 170
  • 301
Platinum Azure
  • 45,269
  • 12
  • 110
  • 134
49

You can accomplish that with a generator like this:

>>> def alternate():
...   while True:
...     yield 0
...     yield 1
...
>>>
>>> alternator = alternate()
>>>
>>> alternator.next()
0
>>> alternator.next()
1
>>> alternator.next()
0
g.d.d.c
  • 46,865
  • 9
  • 101
  • 111
  • This is far more generalizable than the other answers (not limited to 2 values, to 0 and 1, to consecutive values...). – octern Jun 11 '12 at 20:25
  • 5
    `itertools.cycle()` works with any iterable of known values. I don't see how either the `itertools` solution or this one can have its generator switch values at runtime, but I'm sure such a thing is not difficult. – Platinum Azure Jun 11 '12 at 20:28
  • This looks like excactly what I was looking for, will try it out. Thanks! – Yngve Jun 11 '12 at 21:11
  • Conceptually easier to build a boolean toggler with True, False and next() – auro Jul 20 '16 at 23:51
  • I just love Python – Novorodnas Feb 18 '22 at 09:35
21

You can use the mod (%) operator.

count = 0  # initialize count once

then

count = (count + 1) % 2

will toggle the value of count between 0 and 1 each time this statement is executed. The advantage of this approach is that you can cycle through a sequence of values (if needed) from 0 - (n-1) where n is the value you use with your % operator. And this technique does not depend on any Python specific features/libraries.

e.g.

count = 0

for i in range(5):
    count = (count + 1) % 2
    print(count)

gives:

1
0
1
0
1
martineau
  • 119,623
  • 25
  • 170
  • 301
Levon
  • 138,105
  • 33
  • 200
  • 191
20

You may find it useful to create a function alias like so:

import itertools
myfunc = itertools.cycle([0,1]).next

then

myfunc()    # -> returns 0
myfunc()    # -> returns 1
myfunc()    # -> returns 0
myfunc()    # -> returns 1
Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99
  • +1 for the function alias idea. It's like the generator solution (most popular at time of writing) but without having to write out a function definition! – Platinum Azure Jun 11 '12 at 21:01
9

In python, True and False are integers (1 and 0 respectively). You could use a boolean (True or False) and the not operator:

var = not var

Of course, if you want to iterate between other numbers than 0 and 1, this trick becomes a little more difficult.

To pack this into an admittedly ugly function:

def alternate():
    alternate.x=not alternate.x
    return alternate.x

alternate.x=True  #The first call to alternate will return False (0)

mylist=[5,3]
print(mylist[alternate()])  #5
print(mylist[alternate()])  #3
print(mylist[alternate()])  #5
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • 7
    Overly complicated... highly suggest looking into `itertools`. – Platinum Azure Jun 11 '12 at 20:34
  • @PlatinumAzure : Itertools is a better option. (in fact, I upvoted your solution). The above is only to demonstrate a neat trick which can be useful in some circumstances -- the packing into a function part is not recommended. (functions probably shouldn't save state, that's what classes are for...). But the fact that True and False can be used to index arrays as 0 and 1 is neat (I think) – mgilson Jun 11 '12 at 20:39
  • 1
    If you really want to save state in a function, you can use `alternate.x` from within it (instead of using the default trick).. which I have to admit I've used once or twice. (But only once or twice.) – DSM Jun 11 '12 at 20:44
8
from itertools import cycle

alternator = cycle((0,1))
next(alternator) # yields 0
next(alternator) # yields 1
next(alternator) # yields 0
next(alternator) # yields 1
#... forever
Marcin
  • 48,559
  • 18
  • 128
  • 201
7
var = 1
var = 1 - var

That's the official tricky way of doing it ;)

SetSlapShot
  • 1,298
  • 1
  • 21
  • 48
  • That will go from 1 to 0 to 0 to 0 to... (-1) – Platinum Azure Jun 11 '12 at 20:23
  • 3
    @PlatinumAzure No, it won't. Perhaps you read it as `var = var - 1`? Might not be very pythonic, but is better than using `%`. It also works for toggling between any two numeric values. For example, `var = 3 - var` to toggle between `1` and `2`. – Magnus Gustavsson Dec 06 '19 at 15:54
  • Correct... I must have misread it. I don't see any edit history to suggest the answer changed, either. I still downvoted because I don't think it's intuitive/maintainable. – Platinum Azure Dec 07 '19 at 23:49
6

Using xor works, and is a good visual way to toggle between two values.

count = 1
count = count ^ 1 # count is now 0
count = count ^ 1 # count is now 1
octopusgrabbus
  • 10,555
  • 15
  • 68
  • 131
Alex Chamberlain
  • 4,147
  • 2
  • 22
  • 49
6

To toggle variable x between two arbitrary (integer) values, e.g. a and b, use:

    # start with either x == a or x == b
    x = (a + b) - x

    # case x == a:
    # x = (a + b) - a  ==> x becomes b

    # case x == b:
    # x = (a + b) - b  ==> x becomes a

Example:

Toggle between 3 and 5

    x = 3
    x = 8 - x  (now x == 5)
    x = 8 - x  (now x == 3)
    x = 8 - x  (now x == 5)

This works even with strings (sort of).

    YesNo = 'YesNo'
    answer = 'Yes'
    answer = YesNo.replace(answer,'')  (now answer == 'No')
    answer = YesNo.replace(answer,'')  (now answer == 'Yes')
    answer = YesNo.replace(answer,'')  (now answer == 'No')
AcK
  • 2,063
  • 2
  • 20
  • 27
5

Using the tuple subscript trick:

value = (1, 0)[value]
Shawn Chin
  • 84,080
  • 19
  • 162
  • 191
  • 1
    That's a neat trick, but it seems like using this to alternate among any values other than 0 and 1 would get ugly fast. – octern Jun 11 '12 at 20:24
  • 2
    True. This trick is mainly used as an alternative to the ternary operator, but happens to work just as well for the OP's specific case. Just thought I'd throw something different into the mix ;) – Shawn Chin Jun 11 '12 at 20:28
2

Using tuple subscripts is one good way to toggle between two values:

toggle_val = 1

toggle_val = (1,0)[toggle_val]

If you wrapped a function around this, you would have a nice alternating switch.

octopusgrabbus
  • 10,555
  • 15
  • 68
  • 131
2

If a variable is previously defined and you want it to toggle between two values, you may use the
a if b else c form:

variable = 'value1'
variable = 'value2' if variable=='value1' else 'value1'

In addition, it works on Python 2.5+ and 3.x

See Expressions in the Python 3 documentation.

martineau
  • 119,623
  • 25
  • 170
  • 301
Jorge Valentini
  • 397
  • 4
  • 17
1

Simple and general solution without using any built-in. Just keep the track of current element and print/return the other one then change the current element status.

a, b = map(int, raw_input("Enter both number: ").split())
flag = input("Enter the first value: ")
length = input("Enter Number of iterations: ")
for i in range(length):
    print flag
    if flag == a:
        flag = b;     
    else:
        flag = a

Input:
3 8
3
5
Output:
3
8
3
8
3

Means numbers to be toggled are 3 and 8 Second input, is the first value by which you want to start the sequence And last input indicates the number of times you want to generate

Gautam Seth
  • 71
  • 1
  • 4
-1

One cool way you can do in any language:

variable = 0
variable = abs(variable - 1)    // 1
variable = abs(variable - 1)    // 0

SoloVen
  • 11
  • 1
  • 3