Building chains from nested list - python

I have a nested list:
[['мама', 'мыть', '10', 'рама'],
['мыть', 'рама', '5', 'долго'],
['мама', 'мыть', '10', 'рама'],
['мыть', 'рама', '3', 'вчера'],
['мыть', 'рама', '10', 'вчера'],
['рама', 'вчера', '1', 'поздно']]
What I need is to build chains where last two non-digital string elements of one list are equal to first two non-digital string elements of another list, for example in:
['Мама', 'мыть', '10', 'рама']
and
['мыть', 'рама', '5', 'долго']
'мыть', 'рама' are a match, so the final output should be:
[['мама', 'мыть', '10', 'рама', '5', 'долго'],
['мама', 'мыть', '10', 'рама', '3', 'вчера'],
['мама', 'мыть' '10', 'рама', '3', 'вчера', '1', 'поздно']]
Digits are kind of probability and should be left as is. I think there should be some kind of iterative search, but I am not sure.
Any help would be appreciated.

1 - Create a dictionary from your list, with the key being the first two words, combined. Something like:
key: 'Мама_мыть' value: ['Мама', 'мыть', '10', 'рама'],
key: 'мыть_рама' value: ['мыть', 'рама', '5', 'долго'],
... etc ...
2 - Iterate over your list, creating a key from the last two non-numeric values in each entry. And look that value up in the dictionary.
3 - When you find a match, create the output.

Related

How do I stop Python treating list items as one item instead of multiple when appending to another list? [duplicate]

This question already has answers here:
What is the difference between Python's list methods append and extend?
(20 answers)
Closed last month.
I have a list called MBN2 thats values are 15 and 13. I'm trying to append it to another list called BoutNumber2, but when I try to do this it treats MBN2 as one list item ['15', '13'] instead of two. When I print the length of MBN2 it says two so I'm not sure why it's doing this. Here is the block of code
for test4 in soup.select('.fight_card_resume'):
MBN2.append(test4.find('td').get_text().replace('Match ', ''))
for test7 in soup.select('.new_table_holder [itemprop="subEvent"] td'):
BoutNumber.append(test7.get_text().strip())
BoutNumber2 = BoutNumber[0::7]
BoutNumber2.append(MBN2)
and this is what I get when I print BoutNumber2 afterwards
['14', '13', '12', '11', '10', '9', '8', '7', '6', '5', '4', '3', '2', '1', '12', '11', '10', '9', '8', '7', '6', '5', '4', '3', '2', '1', ['15', '13']]
How do I get Python to treat the appended 15 and 13 as seperate?
Just this should work:
BoutNumber2 = BoutNumber2 + MBN2
or you could do
BoutNumber2.extend(MBN2)
Both solutions should do the job.

Python: max(a list of numbers as characters) gives right and wrong answer [duplicate]

This question already has answers here:
Python: sorting string numbers not lexicographically
(5 answers)
Closed 2 years ago.
So here's the exact scenario- consider the list:
x=['4', '5', '29', '54', '4', '0', '-214', '542', '-64', '1', '-3', '6', '-6']
now max(x) should give '542' instead it gives '6', but if you take out '6' it does give '542' as max. min(x) on the other hand correctly gives '-214' as the answer.
if you convert x into a list of numbers then obviously max(x) gives the correct output 542. This is an unreliable behavior at least from what I know about Python and I would like to explore if I am missing something here on how max() function works that could explain this behavior.
As I was writing this question and trying to understand this behavior with max() function, I tried x.sort() and it gave out the answer. So let me paste the sorted list:
['-214', '-3', '-6', '-64', '0', '1', '29', '4', '4', '5', '54', '542', '6']
So basically these are strings and initial character of the string decides its value as string. Meaning, 5kaify will come first than 6kaify .
For more clarity, if I add bunch of alphabets into this list as below:
x=['4', '5', '29', '54', '4', '0','d', '-214', '542', '-64', '1','a', '-3','c', '6', '-6']
max(x) will give 'd' as the answer as alphabetically it would come later than all the strings in the list, hence max() checks for alphabetical order as the value for list of strings/characters and not its integral/numeric value. Hope this was helpful.
You are taking string not int. While taking string: they are sorted alphabetically.
x.sort():
['-214', '-3', '-6', '-64', '0', '1', '29', '4', '4', '5', '54', '542', '6']
You need to use map to convert them into int.
max(map(int,x))
# 542
Here is another approach,
>>> x=['4', '5', '29', '54', '4', '0', '-214', '542', '-64', '1', '-3', '6', '-6']
>>>
>>> max(x, key=lambda x : int(x))
'542'
>>> min(x, key=lambda x : int(x))
'-214'
So essentially max and min when using a string will use alphabetically highest character. Think of the array
['all','b','c','d']
max will list d as the answer as when sorting alphabetically we first rely on the initial character and only with duplicates do we check the next character.
So when we try to sort numbers as a string it will use the same logic. Therefore 6 will be higher than 562 since 6 > 5.
Alphabetically the order is symbols < numbers (in order 0-9) < characters (in order a-z)
I hope that answers your question.

How do I use other elements fom one list?

I have a list of lists:
data = [['2001', '20', '0', '0', '10', '0', '15', '0'],
['2004', '15', '0', '9.5', '13', '10', '18', '30']]
My work is to use items of sublists in this list of lists:
def FinalMark(studentNum):
if studentNum in data:
I don't know what to do next. Let's say if 2001 is the first item of a sublist, I want to know how to use others items of this sublist.
There are better ways to do it by storing the data as a dictionary. But with what you have, you can loop through data:
def FinalMark(studentNum):
for marks in data:
if marks[0] == studentNum:
return sum([float(i) for i in marks[1:]])
marks[1:] is a slice of marks that skips the first element (the student number).

How to work out an average from items within a dict.?

I am new to python so a simplified explanation would be much appreciated!
As of now I have a dictionary that looks like this:
names = {'Bob Smith': ['5', '6', '7', '5'], 'Fred Jones': ['8', '5', '7', '5', '9'], 'James Jackson': ['5','8','8','6','5']}
I need to do the following:
Take the last three items from each of the entries in the dict. e.g. 6, 7, 5 for bob smith.
Calculate an average based upon those values. e.g. Bob smith would be 6.
List the averages in order from highest to lowest (without the dict keys).
So far I have the following enclosed in an if statement:
if method == 2:
for scores in names.items():
score = scores[-1,-2,-3]
average = sum(int(score)) / float(3)
print(average)
I had a look at this thread too but I am still stuck.
Can anyone give me some pointers?
Scores[-1,-2,-3] does not get the last three elements. It gets the element at the key (-1,-2,-3) in a dictionary, which will raise an error in the case of a list. Scores[-3:] would get the last three elements.
When getting the scores, you need to use names.values() instead of names.items()
The python string-to-integer conversions in the int type constructor are not smart enough to handle lists of strings, only individual strings. Using map(int,score) or int(i) for i in score would fix that.
The variable score is also an extremely poor choice of name for a list of elements.
In Python3.4+, there is a statistics module
>>> names = {'Bob Smith': ['5', '6', '7', '5'], 'Fred Jones': ['8', '5', '7', '5', '9'], 'James Jackson': ['5','8','8','6','5']}
>>> import statistics
>>> sorted((statistics.mean(map(int, x[-3:])) for x in names.values()), reverse=True)
[7.0, 6.333333333333333, 6.0]
names = {'Bob Smith': ['5', '6', '7', '5'], 'Fred Jones': ['8', '5', '7', '5', '9'], 'James Jackson': ['5','8','8','6','5']}
def avg(l):
l = list(map(int,l))
return sum(l[-3:])/3
avgs = []
for each in names.values():
avgs.append(avg(each))
avgs.sort(reverse=True)
print avgs
Output:
[7, 6, 6]

How can i sort integers in a list, if they are in a string?

I have a controlled assessment, and need to be able to order scores from a test in numerical and alphabetical order. How do i do this if they are connected to the persons name who completed the quiz. All names are within 1 list, For example ["John, 9"], ["alfie, 6"] etc
any help much appreciated!
If you want to sort a list of strings based on a transformation on each of these strings, you can use the function sorted with the key keyword argument:
>>> l = ['10', '9', '100', '8']
>>> sorted(l)
['10', '100', '8', '9']
>>> sorted(l, key=int)
['8', '9', '10', '100']
>>> def transformation(x):
... return -int(x)
...
>>> sorted(l, key=transformation)
['100', '10', '9', '8']
What the key function does is that the strings are not compared directly, but the values that are returned by the function are.

Categories