How to make two lists out of three on Python3 - python

The goal is: turn 3 lists of the same length into 2 lists, the length of which does not differ by more than 1, elements from different source lists must alternate and their order must not be violated. For example: if ‘A’ went before ' B’ in the source list, then ‘B’ cannot go before ‘A’ in the final list.
So, I decided to wrote a function:
def list_3_2(list1,list2,list3):
#split all lists in one list
a=sum((list(i) for i in zip(list1,list2,list3)),[])
#I want to separate list "a" to two new lists: l1 and l2
l1=[]
l2=[]
#//////
return(l1,l2)
list_3_2(['1','2','3'],['4','5','6'],['7','8','9'])
Then I faced the problem of separation. I found some similar issues, but their lists were structured differently, like main_list=['3 5', '1 2', '1 7']. I get the another result, after the unification: a=['1', '4', '7', '2', '5', '8', '3', '6', '9']. How could i separate this list?

Maybe I'm misunderstanding the question.
from itertools import chain
def list_3_2(l1, l2, l3):
x = list(chain.from_iterable(zip(l1, l2, l3)))
m = len(x) // 2
return (x[:m], x[m:])
Zip the lists, concatenate the resulting tuples into a single list, then split that in half.

Well, according to the finalizing information you shared, I believe you were extremely close to the solution, you just needed to split the final array. What do you think about this?
def list_3_2(list1,list2,list3):
a=sum((list(i) for i in zip(list1,list2,list3)),[])
return a[:len(a)//2], a[len(a)//2:]
print(list_3_2(['1','2','3'],['4','5','6'],['7','8','9']))
Basically, splitting the list into two parts, where one is at most 1 element larger than the other, corresponds to splitting an arbitrary list at the index of the rounded-down midpoint. The parts will be of different length iff the original array (chain of inputs) has odd length.
The midpoint index of an array is len(array)//2 - len(array) is the full length and //2 is the operation of "division in half rounded down".
Lastly, to split the array using this midpoint index, we use the splicing mechanism in python. The syntax is as follows:
a[:m] = all elements of a from index 0 (= the beginning) to index m-1.
a[m:] = all elements of a from index m to index len(a) - 1 (= the end).

Hey try that hope is that what you want
def list_3_2(list1,list2,list3):
#split all lists in one list
#I want to separate list "a" to two new lists: l1 and l2
a=[]
[a.extend(j) for j in (list(list(i) for i in zip(list1,list2,list3)))]
#//////
div=int(len(a)/2)
l1=a[0:div]
l2=a[div:]
return l1,l2
print(list_3_2(['1','2','3'],['4','5','6'],['7','8','9']))

Related

Return possible permutations for given array

For a given list with string digits, I want to return the different string numbers that can be generated using all the elements in the list (so if there are 5 elements, the number should consist of 5 digits).
The task is to return the possible permutations, the smallest permutation and the maximum permutation in a list.
answer should be converted to integers
If '0' is present in the input, it will produce string numbers with leading zeroes, this is not taken into account when they are converted to integers.
This is my code now:
from itertools import permutations
def proc_arr(arr):
lst = [] # define new list
list_of_tuples = list(permutations(arr, len(arr))) # now they are tuples in a list
# convert to integers in list
separator = [map(str,x) for x in list_of_tuples]
together = [int(''.join(s)) for s in separator]
# append to new list and return the len of possible combinations, min and max value
lst.append(len(together))
lst.append(min(together))
lst.append(max(together))
#print(lst)
return lst
proc_arr(['1','2','2','3','2','3'])
However, I don't understand why I do don't get the right amount of permutations.
input: proc_arr(['1', '2', '2', '3', '2', '3']) output: [60, 122233, 332221]
and I get [720, 122233, 332221]
another example of input & output
input: proc_arr(['1','2','3','0','5','1','1','3']) output: [3360, 1112335, 53321110]
You appear to be counting the same permutation multiple times because you re treating digits that appear multiple times as distinct. That is, for example, 122233 and 122233 are each counted because one has the "first" 3 first, and the second does not.
One solution would be to compute how many duplicates you will have and eliminate them from your count. In your example, there are 3 2s, so there are 1*2*3=6 ways they can be arranged whilst leaving everything else the same; thus, your answer is 6 times too big due to the 2's. Similarly for the 2 3s: 1*2=2 ways, so divide your answer by 2. This gets you to 720/6/2 = 60, the correct answer.

Iterating through and selecting nth element in multiple lists of lists - python 2

I have multiple lists of lists. I need to get the 2nd element of each inner list and make multiple new lists composed of these 2nd elements.
Sample data:
for item in list:
x = fpp.table
print x
[['hello', 'mum'],['goodbye', 'dad']]
[['3', '6', '9'], ['2', '4', '6']]
So with this data I want to turn it into the two following lists:
['mum','dad']
['6','4']
The accepted answer is correct. However, the most Pythonic (IMO) way to do that is (BTW, you should avoid to name your variable list since this is a type in Python) to use a list comprehension:
[elt[1] for elt in my_list]
If you want to get the second element of each list only when the list has at least two elements (otherwise, the previous code would crash), you can add a condition to the list comprehension:
[elt[1] for elt in my_list if len(elt) >= 2]
Lets try making a function like this:
def secondElement(list):
secondL = []
for item in list:
secondL.append(item[1])
print (secondL)
This should do the job for getting the 2nd element of the every integrated sub-list from the main list. Hope this is what you were looking for!

Include empty values in a list according to specific positions (Python)

I have the following list:
CompleteList=['00:00:00', '00:00:01', '00:00:02', '00:00:03',....,'23:59:59']
and I also have the following list:
IncompleteList=['00:00:00', '00:00:01', '00:00:03',....,'23:59:59']
As it can be seen the CompleteList has values that are missing in the IncompleteList, as for example value '00:00:02'.
I also have a third array:
MyList=['22', '33', '25',....,'13']
What I need is to include empty values in MyList in those position where IncompleteList has missing values in the following way:
MyList_result=['22', '33','','25',....,'13']
I have achieved this in the following way:
MyList_result=[]
for item in CompleteList:
if item in IncompleteList:
ind=IncompleteList.index(item)
v=MyList[ind]
MyList_result.append(v)
else:
v=''
MyList_result.append(v)
This works but it takes too long taking into account the size of the lists that I am working with. I really need to find a more efficient way of doing it. Any help will be appreciated.
The first intuitive approach would be to convert the IncompleteList to a set and get an iterator for MyList. Then it becomes a linear operation in iterating over CompleteList and spit out the next item from the MyList iterator if the elem from CompleteList is present in IncompleteList else as per your example an empty string
Sample Code
IncompleteList=['00:00:00', '00:00:01', '00:00:03','23:59:59']
IncompleteSet = set(IncompleteList)
MyList=['22', '33', '25','13']
CompleteList=['00:00:00', '00:00:01', '00:00:02', '00:00:03','23:59:59']
MyListIt = iter(MyList)
[next(MyListIt) if cl_elem in IncompleteSet else '' for cl_elem in CompleteList]
Sample Output
Out[100]: ['22', '33', '', '25', '13']
Alternatively you can zip both the IncompleteList and MyList and convert the paired list as a dictionary. Following which iterate over the CompleteList and spit out the corresponding value from the dictionary if the element is present else an empty string
MyDict = dict(zip(IncompleteList, MyList))
[MyDict.get(k, '') for k in CompleteList]
Out[108]: ['22', '33', '', '25', '13']
The bottleneck from your implementation is in two places:
You are checking for each item from the CompleteList in the IncompleteList at
if item in IncompleteList:
which in the worst case would scan the IncompleteList n number of times (if n is the number of elements in the CompleteList)
If the item is present you find the index of the item at
ind = IncompleteList.index(item)
which involves another scan of the IncompleteList
The first solution suggested by #Abhijit solves the second problem where you do not have to scan the list a second time to get the index. However the check for the presence of the item in the IncompleteList/IncompleteSet is still a bottleneck.
If we can assume sorted lists then the following solution will be faster although a little more complex:
MyList_result = []
incomplete_list_index = 0
incomplete_list_length = len(IncompleteList)
for item in CompleteList:
if incomplete_list_index < incomplete_list_length and IncompleteList[incomplete_list_index] == item:
MyList_result.append(MyList[incomplete_list_index])
incomplete_list_index += 1
else:
MyList_result.append('')
This involves just a single pass of the CompleteList (and no pre-processing to generate a Dict as the second solution suggested by #Abhijit).

extract from a list of lists

How can I extract elements in a list of lists and create another one in python. So, I want to get from this:
all_list = [['1 2 3 4','2 3 4 5'],['2 4 4 5', '3 4 5 5' ]]
a new list like this:
list_of_lists = [[('3','4'),('4','5')], [('4','5'),('5','5')]]
Following is what I did, and it doesn't work.
for i in xrange(len(all_lists)):
newlist=[]
for l in all_lists[i]:
mylist = l.split()
score1 = float(mylist[2])
score2 = mylist[3]
temp_list = (score1, score2)
newlist.append(temp_list)
list_of_lists.append(newlist)
Please help. Many thanks in advance.
You could use a nested list comprehension. (This assumes you want the last two "scores" out of each string):
[[tuple(l.split()[-2:]) for l in list] for list in all_list]
It could work almost as-is if you filled in the value for mylist -- right now its undefined.
Hint: use the split function on the strings to break them up into their components, and you can fill mylist with the result.
Hint 2: Make sure that newlist is set back to an empty list at some point.
Adding to eruciforms answer.
First remark, you don't need to generate the indices for the all_list list. You can just iterate over it directly:
for list in all_lists:
for item in list:
# magic stuff
Second remark, you can make your string splitting much more succinct by splicing the list:
values = item.split()[-2:] # select last two numbers.
Reducing it further using map or a list comprehension; you can make all the items a float on the fly:
# make a list from the two end elements of the splitted list.
values = [float(n) for n in item.split()[-2:]]
And tuplify the resulting list with the tuple built-in:
values = tuple([float(n) for n in item.split()[-2:]])
In the end you can collapse it all to one big list comprehension as sdolan shows.
Of course you can manually index into the results as well and create a tuple, but usually it's more verbose, and harder to change.
Took some liberties with your variable names, values would tmp_list in your example.

Extract certain elements from a list

I have no clue about Python and started to use it on some files. I managed to find out how to do all the things that I need, except for 2 things.
1st
>>>line = ['0', '1', '2', '3', '4', '5', '6']
>>>#prints all elements of line as expected
>>>print string.join(line)
0 1 2 3 4 5 6
>>>#prints the first two elements as expected
>>>print string.join(line[0:2])
0 1
>>>#expected to print the first, second, fourth and sixth element;
>>>#Raises an exception instead
>>>print string.join(line[0:2:4:6])
SyntaxError: invalid syntax
I want this to work similar to awk '{ print $1 $2 $5 $7 }'. How can I accomplish this?
2nd
how can I delete the last character of the line? There is an additional ' that I don't need.
Provided the join here is just to have a nice string to print or store as result (with a coma as separator, in the OP example it would have been whatever was in string).
line = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
print ','.join (line[0:2])
A,B
print ','.join (line[i] for i in [0,1,2,4,5,6])
A,B,C,E,F,G
What you are doing in both cases is extracting a sublist from the initial list. The first one use a slice, the second one use a list comprehension. As others said you could also have accessed to elements one by one, the above syntaxes are merely shorthands for:
print ','.join ([line[0], line[1]])
A,B
print ','.join ([line[0], line[1], line[2], line[4], line[5], line[6]])
A,B,C,E,F,G
I believe some short tutorial on list slices could be helpfull:
l[x:y] is a 'slice' of list l. It will get all elements between position x (included) and position y (excluded). Positions starts at 0. If y is out of list or missing, it will include all list until the end. If you use negative numbers you count from the end of the list. You can also use a third parameter like in l[x:y:step] if you want to 'jump over' some items (not take them in the slice) with a regular interval.
Some examples:
l = range(1, 100) # create a list of 99 integers from 1 to 99
l[:] # resulting slice is a copy of the list
l[0:] # another way to get a copy of the list
l[0:99] # as we know the number of items, we could also do that
l[0:0] # a new empty list (remember y is excluded]
l[0:1] # a new list that contains only the first item of the old list
l[0:2] # a new list that contains only the first two items of the old list
l[0:-1] # a new list that contains all the items of the old list, except the last
l[0:len(l)-1] # same as above but less clear
l[0:-2] # a new list that contains all the items of the old list, except the last two
l[0:len(l)-2] # same as above but less clear
l[1:-1] # a new list with first and last item of the original list removed
l[-2:] # a list that contains the last two items of the original list
l[0::2] # odd numbers
l[1::2] # even numbers
l[2::3] # multiples of 3
If rules to get items are more complex, you'll use a list comprehension instead of a slice, but it's another subjet. That's what I use in my second join example.
You don't want to use join for that. If you just want to print some bits of a list, then specify the ones you want directly:
print '%s %s %s %s' % (line[0], line[1], line[4], line[6])
Assuming that the line variable should contain a line of cells, separated by commas...
You can use map for that:
line = "1,2,3,4,5,6"
cells = line.split(",")
indices=[0,1,4,6]
selected_elements = map( lambda i: cells[i], indices )
print ",".join(selected_elements)
The map function will do the on-the-fly function for each of the indices in the list argument. (Reorder to your liking)
You could use the following using list comprehension :
indices = [0,1,4,6]
Ipadd = string.join([line[i] for i in xrange(len(line)) if i in indices])
Note : You could also use :
Ipadd = string.join([line[i] for i in indices])
but you will need a sorted list of indices without repetition of course.
Answer to the second question:
If your string is contained in myLine, just do:
myLline = myLine[:-1]
to remove the last character.
Or you could also use rstrip():
myLine = myLine.rstrip("'")
>>> token = ':'
>>> s = '1:2:3:4:5:6:7:8:9:10'
>>> sp = s.split(token)
>>> token.join(filter(bool, map(lambda i: i in [0,2,4,6] and sp[i] or False, range(len(sp)))))
'1:3:5:7'
l = []
l.extend(line[0:2])
l.append(line[5]) # fourth field
l.append(line[7]) # sixth field
string.join(l)
Alternatively
"{l[0]} {l[1]} {l[4]} {l[5]}".format(l=line)
Please see PEP 3101 and stop using the % operator for string formatting.

Categories

Resources