问题
I need to populate a list with 5 positions.
new_list = ___ ___ ___ ___ ___
I receive 2 lists and I have one default value to populate the new list.
Now start the problems:
In the good way, I receive 2 values from listA and 2 values from listB and add the default value
A1 A2 DEFAULT B1 B2
But now, if for example listA is empty I need to populate in another way:
DEFAULT B1 B2 B3 B4
the same if listB is empty.
In case listA just has 1 element, and listB another element it should be:
A1 DEFAULT B1
EDIT: the listA and listB have much more objects
回答1:
You can solve this by recursively building the list with a and b, starting with the default user.
def build_list(listA,listB,default=None):
if default is None:
default = [DEFAULT_USER]
if len(default) == 5 or len(listA) + len(listB) == 0:
return default
else:
default = listA[:1] + default + listB[:1]
return build_list(listA[1:],listB[1:],default)
This will add one element of listA to the beginning and one element of listB to the end until the length of default is 5. if either of the lists becomes empty, it will simply add nothing from that list, giving the exact behavior you wanted.
It keeps going until either all input lists are of length 0 or the default is of length 5. This method will work on lists of any length including zero, but will not preserve the ordering of the elements from list A.
Some tested examples:
>>> DEFAULT_USER=1000
>>> build_list([1],[2])
[1,1000,2]
>>> build_list([],[1,2,3,4,5,6,7,8,9])
[1000, 1, 2, 3, 4]
>>> build_list([1,2,3,4,5],[6,7,8,9,10])
[2, 1, 1000, 6, 7]
>>> build_list([1,2,3,4,5,6,7,8,9],[])
[4, 3, 2, 1, 1000]
回答2:
This will work in all cases, including if list B is less than 2 elements long while list A is 4 or greater.
avail_a = len(list_a)
avail_b = min(len(list_b), 2) # assume that we are taking max 2 elements from B
num_a = min(avail_a, 4 - avail_b) # take either all of A (if len < 2), or remainder from the total
num_b = 4 - num_a # take (up to) remainder of total
final_list = list_a[:num_a] + [DEFAULT] + list_b[:num_b]
If there are at least 2 elements in lists A and B, we will take 2 from A, and 2 from B.
If there are less than 2 elements in A, avail_a < 4 - avail_b
, so num_a == len(list_a)
. num_b
will get assigned the remainder of the 4 available slots. If num_b
is larger than len(list_b)
no error will be thrown by list_b[num_b]
If there are less than 2 elements in B, num_a
will be equal to either the remaining number of slots out of the 4, or len(list_a)
, whichever is smaller.
回答3:
I think you can do something like this:
new_list = [DEFAULT]
# First append listB elements from start until you reach the end
# or until you append enough elements according to the length of listA
i = 0
b_limit = min(len(listB), max(2, 4 - len(listA)))
while i < b_limit:
new_list.append(listB[i])
# Then prepend listA elements from end until you raech the start
# or until you've got a total of 5 elements.
i = 0
a_limit = min(len(listA), 5-len(new_list))
while i < a_limit:
new_list.insert(0, listB[-i-1])
Which should be "simplifiable" as:
new_list = listA + [DEFAULT] + listB
new_list = new_list[:(len(listA) + 1 + max(2, 4 - len(listA)))][-5:]
回答4:
You could just add your lists:
new_list = listA + listB
# add the default value
new_list.append(DEFAULT)
来源:https://stackoverflow.com/questions/38441568/populating-a-list-in-a-specific-way