0

I've got a simple function:

def foo(inp):
    i = 0
    while (i < len(inp)):
        yield {i,inp[i]}
        i = i+1

for x in foo(("a", "b", "c")):
    print(x)

which I expect to print

{0, 'a'}
{1, 'b'}
{2, 'c'}

but it sometimes prints

{0, 'a'}
{1, 'b'}
{'c', 2}

Why are the last tuple's members swapped?

To make it stranger, adding "d" to the input list, I see three different outputs. Either all outputs are in order, I get only {'d',3) swapped, or I get both {'c',2) and {'d',3) swapped

sys.version: 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)]

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • As stated in the docs, set sare [Unordered collections of unique elements](https://docs.python.org/2/library/sets.html) – yatu Feb 12 '19 at 12:05
  • 2
    Not really sure what you're trying to accomplish, but it looks like you probably want to yield tuples rather than sets. Edit: Welp, I just realized that you *thought* you were yielding tuples all along. Curly braces `{1,2}` make a set, while parentheses `(1,2)` make a tuple. – Aran-Fey Feb 12 '19 at 12:06
  • @Aran-Fey: Yup, that was the problem. The "only {'c', 2}` gets swapped" was a red herring. `{0, 'a'}` is also a set and could have been swapped, it just didn't happen in my tests. – MSalters Feb 12 '19 at 12:13
  • yield a dict instead a collection. collections are unordered (no warranted order). – Felix Martinez Feb 12 '19 at 12:21
  • @FelixMartinez: Apparently worse than just no _warranted_ order, it's not even _consistent_ across runs. But this was indeed a case of "off-topic, simple typo". The intent was very much not to sort the outputs. It's basically a generator equivalent to `zip(range(len(inp)), inp)` – MSalters Feb 12 '19 at 12:29

0 Answers0