-3

I have a list of values in a list. The length of the list is variable from 1-5. If the list is less than the maximum_length then the list should be expanded, but should never exceed the max length.

I want to expand the list incrementally to distribute the items across the list starting from the first item. Below is the input list and the desired output. The amount of items duplicated is correct, but the order is not.

This list can be string values, so simply sorting the list is not a solution.

Example 1

current_list: ['#f8f8f8']
result: ['#f8f8f8', '#f8f8f8', '#f8f8f8', '#f8f8f8', '#f8f8f8']
desired result: ['#f8f8f8', '#f8f8f8', '#f8f8f8', '#f8f8f8', '#f8f8f8']

Example 2

current_list: ['#090909', '#171717']
result: ['#090909', '#171717', '#090909', '#171717', '#090909']
desired result: ['#090909', '#090909', '#090909', '#171717', '#171717']

Example 3

current_list: ['#d8d8d8', '#ececec', '#f1f1f1']
result: ['#d8d8d8', '#ececec', '#f1f1f1', '#d8d8d8', '#ececec']
desired result: ['#d8d8d8', '#d8d8d8', '#ececec', '#ececec', '#f1f1f1'] 

Example 4

current_list: ['#ecede7', '#eff0eb', '#f1f2ed', '#ffffff']
result: ['#ecede7', '#eff0eb', '#f1f2ed', '#ffffff', '#ecede7']
desired result: ['#ecede7', '#ecede7', '#eff0eb', '#f1f2ed', '#ffffff']

Below is my code to produce the list. How can I update this to get the desired output?

print([current_list * max_len][0][:max_len])

Updated to show that using sort isn't what I need. The purpose of this question is to maintain the distribution of the original list.

stwhite
  • 3,156
  • 4
  • 37
  • 70
  • Do you just want to sort the final list? then call `sorted()` with the final list – Andrej Kesely Oct 30 '22 at 23:47
  • @AndrejKesely I just clarified the question to state that this list can be any strings. So in this case this suggestion wouldn't be the solution, but thank you – stwhite Oct 30 '22 at 23:57
  • Can you please post an example and expected output with string values? – Andrej Kesely Oct 31 '22 at 00:00
  • It's the exact same. The solution should work with numbers or strings. The current example is still valid. – stwhite Oct 31 '22 at 00:01
  • Again, please post an example and expected output with string values. You just say "it's exactly the same", but then why not just use `sort`? Are you thinking of a case where numbers and strings both appear? If so, what would be the output? – j1-lee Oct 31 '22 at 00:10
  • Because, sort will destroy the order when it comes to strings. This is the reason why I said the requirement of this solution is that it work without using sort. The output has been changed so that you can see that they're strings. – stwhite Oct 31 '22 at 00:17
  • 1
    Now I see you replace all integers with corresponding strings. But I still don't see why you can't use `sort`, and what you are expecting for general string values, because `sort` will produce all the outputs in your examples. If `sort` destroys the order, then what do you want to do? What "order" do you want to "preserve"? – j1-lee Oct 31 '22 at 00:18
  • 1
    @stwhite So you want to preserve the order or "occurrence"? Then that is totally not related to having the possibility of strings as values or not. – j1-lee Oct 31 '22 at 00:26
  • @j1-lee the string values have been added. The order is based on an implied distribution from my data, therefore the order of original list should be maintained and duplicates are inserted following each value. – stwhite Oct 31 '22 at 00:50
  • You're adding more complex examples but still failing to demonstrate a desired result which couldn't be achieved with a simple **`sort`**. Meaning, all your examples would have the desired result if you just used **regular `sort`**. Instead, you should have just given an example like `['a', 'z', 'k']` - see my answer below, esp the example `['2','3','4', '1']`. – aneroid Oct 31 '22 at 00:52
  • Your answer solved it. Apologies for saying sort. I meant that it can't be sorted alphabetically or by number. – stwhite Oct 31 '22 at 00:58
  • @stwhite _"I meant that it can't be sorted alphabetically"_ but you kept editing & adding examples which are clearly solved just by simple sorting. Any other example could have been used to demonstrate your desired result. In the long wall of text and code that is your question, only your current edit mentions that and I had already answered the question by then. It was [j1-lee's comment above which clarified your intent](https://stackoverflow.com/questions/74257498/repeat-items-in-list-and-maintain-order-of-occurrence-until-maximum-length-of-li/74257775#comment131102299_74257498). – aneroid Oct 31 '22 at 01:05

1 Answers1

1

Use sort as explained in the comments and to maintain the distribution of the original list, the sort key should be the index of the element in your original list.

max_len = 5
current_list = ['1','2','3','4']
inter = [current_list * max_len][0][:max_len]  # assume we stick with your function
# ['1', '2', '3', '4', '1']
sorted(inter, key=current_list.index)
# ['1', '1', '2', '3', '4']

Works with any order, sorts on the original order.

current_list = ['2','3','4', '1']
inter = [current_list * max_len][0][:max_len]
sorted(inter, key=current_list.index)
# ['2', '2', '3', '4', '1']

If your list is larger, you can use a more efficient key for the sort, like a dictionary which stores the elements and keys and their index as values.

Here are some other answers discussing sorting like this.

aneroid
  • 12,983
  • 3
  • 36
  • 66
  • 1
    Btw, a better way to create that repeating list up to a maximum length, esp for large lists is [`itertools.cycle`](https://docs.python.org/3/library/itertools.html#itertools.cycle) with `itertools.islice`. – aneroid Oct 31 '22 at 00:59