2

While learning about map(function, *iterables) function, I found that it applies the function with n number of arguments where n is the number of supplied iterables as args to the map() function. So, I tried and it's working as expected.

Another point is lists in Python maintain the insertion order while sets are unordered. Apart from having all these details, I'm unable to understand that -

Why does applying map() on a set and then converting the resultant map object to a list give me a sorted list while applying map() on a list and then converting the map object to a list gives me a list with the same order as it was in the supplied list?

This is my source code:

l1 = [1, 2, 4, 5, 3]
s1 = {6, 7, 9, 8, 0}

print(list(map(lambda num: num * 2, l1)))
print(list(map(lambda num: num * 2, s1)))

and this is the output:

[2, 4, 8, 10, 6]
[0, 12, 14, 16, 18]

In case of:

print(list(map(lambda num: num * 2, s1)))

each time I run the program, I'm getting the same sorted list but if I print(s1) I'm getting different orders of s1. Shouldn't I get a list with random order of doubled numbers each time I run the program?

P.S.

Another user, suggested me a possible duplicate order-of-unordered-python-sets. But, if possible, I seek an updated answer for this question that talks about the implementation of sets in current versions of Python (as of now the current version is 3.10.7).

The order-of-unordered-python-sets definitely gives a base to under the reason behind this problem. But please provide your updated answers here so that it'll be relevant for upcoming years. Otherwise, you can definitely vote to close it.

Shubham
  • 1,153
  • 8
  • 20
  • 1
    General note: unordered / not ordered does not mean that the order is random, it simply means that you must not rely on any order, even / especially if you think you found some order in it. I am not getting a different order for `print(s1)` during subsequent runs, at least not the first 5 times. – luk2302 Oct 11 '22 at 15:48
  • the question has nothing to do with `maps` or lambdas. If you simply add `print(s1)` to your example, you can see how python rearranged your set. If you experiment with other numbers, you will find that set members are not always sorted. – gog Oct 11 '22 at 15:49
  • Thanks for this valuable comment @luk2302. But I can't seem to find any logical explanation for this. I tried searching in `pydoc3 list`, thought may be I'll find some method where it explains how `list()` converts a `map` object to `list`, but instead got nothing. – Shubham Oct 11 '22 at 15:50
  • Yes, @gog and that's really what I'm concerned about. If `print(s1)` always gives me a rearranged set and if passing `map(func, list1)` to `list()` always gives me another `list2` with the same arrangement of elements of `list1` after applying `func`, then why it sorts in case of `set`? After each run, I should get a rearranged list in case of `list(map(func, set1))`. Shouldn't I? – Shubham Oct 11 '22 at 15:54
  • 1
    @Shubham: no, the internal order of the set is deterministic, it only depends on the elements and the python engine version. The same python will always iterate the same elements in the same way. – gog Oct 11 '22 at 15:56
  • Does this answer your question? ['order' of unordered Python sets](https://stackoverflow.com/questions/12165200/order-of-unordered-python-sets) – luk2302 Oct 11 '22 at 16:08
  • @gog Is there any way to find out about the internal order of the set? luk2302's answer seems relevant in my case. But most of the time when I put 5 or 4 single-digit numbers in the set, it's happening. – Shubham Oct 11 '22 at 16:08
  • Thanks @luk2302. The link is indeed valuable. I found mgilson's and abarnert's answer interesting but it talks about Python versions prior to 3.6 using CPython. All those answer's does give a base to understand this problem but they should be updated for newer versions of Python. – Shubham Oct 11 '22 at 16:23

2 Answers2

2

You picked a very bad sample since {6, 7, 9, 8, 0} is printed as {0, 6, 7, 8, 9} which appears to be sorted, but it is not, it just happens to be the same order as something that is sorted. Pick {16, 6, 7, 9, 8, 0} instead and you will see {0, 16, 6, 7, 8, 9} in the output, obviously not sorted or ordered.

(Unordered) sets do have an order that you MUST NOT rely on, even / especially if you think you found order in it. Any order you see is purely by chance.

luk2302
  • 55,258
  • 23
  • 97
  • 137
  • Indeed, this is the case. I tried printing 4 sets, one with the values that you suggested. Most of the sets with 5 single-digit numbers are getting printed in a manner that seems like they are sorted. I want to deep dive into this, why's it happenning? What can I do more? – Shubham Oct 11 '22 at 16:05
0

sets are unordered (not randomly ordered), in your case, it was just a coincidence that your specific series of elements were printed in order. If you run the same code but with different set elements, they may end up being out of order.

japnoo
  • 36
  • 3
  • Thanks for the answer @japnoo. I think I've mentioned in the question that `set`s are unordered and also as you asked me to do, I tried with `s2 = {7, 2, 4, 9, 3}` and `print(list(map(lambda num: num * 2, s2)))` and yet again I got the output as `[4, 6, 8, 14, 18]`. – Shubham Oct 11 '22 at 15:59
  • @Shubham another bad sample, put larger values in your set. – luk2302 Oct 11 '22 at 15:59