0

I have a list of tuples. These tuples include an integer value and a category.

mylist = ((1,catA),(1,catB),(2,catA),..)

My objective is to select one tuple from the list that has a value = minimum value. There could be one or more of the tuples that have a value = minimum value. In the example above the minimum value is 1 and both CatA and CatB have value = minimum value.

To get min value I used:

min_value = min(mylist , key=lambda x: x[0])[0]

To select a tuple with a value = min_value I used:

min_tuple = min([x for x in mylist if x[0] == min_value])

However I would like to randomize the sort order so that the selected tuple doesn't always have the same category.

I tried using shuffle before selecting min_tuple but that didn't change the selection order.

random.shuffle(mylist)
min_tuple = min([x for x in mylist if x[0] == min_value])

So I am guessing that the min_tuple expression does it's own ordering. Is this true? If true, can the min_tuple expression ordering be randomized as it selects a tuple with value = min_value?


Edit to add:

I was aware of random.choice from other SO question/answers and elsewhere but my question was focused on the min tuple expression specifically how/if it ordered tuples as it found min value in list.

Also my specific formulation incorrectly or needlessly did a 'double filter' for min value (eg == min_value and min() ). The answer I received here corrected this usage and also applied random.choice as a modification of my specific method.

curtisp
  • 2,227
  • 3
  • 30
  • 62
  • Duplicate of [How do I randomly select an item from a list using Python?](http://stackoverflow.com/questions/306400/how-do-i-randomly-select-an-item-from-a-list-using-python). The only question here is, "How do I randomly select an element of a list?" You already know how to filter down to the tuples with the minimum value. – jpmc26 Jun 20 '16 at 01:10
  • Not quite. Pls see accepted answer. I needed to ask this particular question. – curtisp Jun 20 '16 at 01:18
  • The accepted answer just uses `random.choice`, as does the accepted answer in the other question. There's no new information here. – jpmc26 Jun 20 '16 at 02:00
  • It was more than just knowing about random.choice. I was doing something wrong and was corrected. – curtisp Jun 20 '16 at 02:21
  • Either that wasn't the question you asked or your question was multiple questions and too broad, then. Synthesizing information from different sources is a skill you *need* as a developer, and you didn't do that here, even though the correct way to do it was made readily available to you. Seeing the correct way should have been enough for you to figure out that something was wrong with your approach, and from there, you might could have asked for clarification on behavior of `min` on `tuple`s, although I suspect that would be a duplicate, too. – jpmc26 Jun 20 '16 at 04:00
  • Ok thanks appreciate the input. – curtisp Jun 20 '16 at 04:14

1 Answers1

3

The min call in your computation of min_tuple means that you're always going to get the tuple with the category that compares smallest. If that was what you really wanted, you should just do min(mylist) and be done with it.

If you want to randomly select from the tuples that have the minimum value, replace min with something like random.choice:

min_value = min(x[0] for x in mylist)
min_tuple = random.choice([x for x in mylist if x[0] == min_value])

Note that I've changed the calculation of min_value to work a little more directly (rather than finding the first tuple with the minimum value and then extracting just the value from it). The original way would have worked fine too.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • Ah ok, I was getting min twice. Seems obvious now, and so does adding random.choice which works perfectly for my needs. – curtisp Jun 20 '16 at 01:17