2

I have two questions.

First Question:

I would like to know how I can remove each second element and third element from a 2-D list questions, so that if the variable questions initially is as follows:

>>> questions
>>> [['Johny', 'Baby', 'Shaw', '1984'], ['Andrew', 'fJKC', 'cbv bv', '1975'], ['Harry', 'Jack', 'Son', '1993']]

The resulted outcome becomes:

>>> questions
>>> [['Johny', '1984'], ['Andrew', '1975'], ['Harry', '1993']]

Second Question:

How can I find a way knowing two values: (minimum value, maximum value), to print whatever of the three lists in the list questions which the last element is in the range (minimum value, max value).

Expected outcome:

If, following obviously the previous outcome, for example, the minimum value is 1980 and the maximum value is 2000. It prints the following:

>>> ['Johny', '1984'], ['Harry', '1993']

Here's my attempt:

beginning = int(input('Beginning: '))
ending = int(input('Ending: '))
position = []
for anyitem in range((len(questions)-1)):
    position1 = int(questions[anyitem][2][-4:])
        if beginning < position1 < ending:
            print(questions[anyitem][3])
        else:
            pass

Please, do not use numpy or any functions that need to be imported. Also, please make the solution general, so it can be applied to a 2D list with not only 3 elements (as in my case) but many elements (for everyone).

5 Answers5

3

Both can be easily accomplished with list comprehensions.

Removing certain elements:

>>> nquestions = [[i ,j] for i, *_, j in questions]
>>> nquestions
[['Johny', '1984'], ['Andrew', '1975'], ['Harry', '1993']]

Here we unpack from each sub-list tossing away the middle elements with *_ while keeping the first and last in order to create the new list from them.

For filtering, it is best to create a custom range and use another list comprehension to filter out the values that are in that range:

>>> r = range(1980, 2000)
>>> [i for i in nquestions if int(i[1]) in r]
[['Johny', '1984'], ['Harry', '1993']]

int(i[1]) required due to the fact that the values are strings. Apart from being very intuitive, membership tests for range objects are quite efficient (See: Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3?).

Community
  • 1
  • 1
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
0

both are very easy to do with list comprehensions & conditions:

questions = [['Johny', 'Baby', 'Shaw', '1984'], ['Andrew', 'fJKC', 'cbv bv', '1975'], ['Harry', 'Jack', 'Son', '1993']]

print([x[:1]+x[3:] for x in questions])

result:

[['Johny', '1984'], ['Andrew', '1975'], ['Harry', '1993']]

with the filtering on year:

print([x[:1]+x[3:] for x in questions if int(x[-1])>=1980 and int(x[-1])<=2000])

result:

[['Johny', '1984'], ['Harry', '1993']]

note that listcomps are not the best when you need a temp variable/side effect (like above: int(x[-1]) must be computed twice, in the case of years we could take a shortcut and use string comparison as well, works from year 1000 to 9999:

print([x[:1]+x[3:] for x in questions if x[-1]>="1980" and x[-1]<="2000"])

When we reach year 10000, I'll edit my answer :)

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

Question 1:

questions = [['Johny', 'Baby', 'Shaw', '1984'], ['Andrew', 'fJKC', 'cbv bv', '1975'], ['Harry', 'Jack', 'Son', '1993']]
new_questions = [[lst[0], lst[3]] for lst in questions]

Question 2, assuming you want to use the original questions list.:

in_range = [[lst[0], lst[3]] for lst in questions if int(lst[3]) in range(1980, 2001)]
blacksite
  • 12,086
  • 10
  • 64
  • 109
0

Removing the 1st and 2nd index is relatively simple, one way to do this (destructively) is to use slice assignment:

>>> for d in questions:
...     d[1:3] = []
>>> questions
[['Johny', '1984'], ['Andrew', '1975'], ['Harry', '1993']]

List comprehensions can also achieve this, but do need to construct a new list (and potentially intermediate lists).

The finding min and max just needs the key argument (updated to include the filter requirement):

>>> min(filter(lambda x: int(x[1])>1980, questions), key=lambda x: x[1])
['Johny', '1984']
>>> max(filter(lambda x: int(x[1])<2000, questions), key=lambda x: x[1])
['Harry', '1993']
AChampion
  • 29,683
  • 4
  • 59
  • 75
0

For your First question this code should do it just fine

>>> for d in questions:
...     d[1:3] = []

my answer for your second question is

>>> min(questions, key=lambda x: x[1])
    ['Harry', '1993']

>>> max(questions, key=lambda x: x[1])
['Harry', '1993']
Ayyoub
  • 4,581
  • 2
  • 19
  • 32