Try using tuple[int, ...] for your type hint for position:

from typing import Optional


def is_none(position: tuple[int, ...], board: list[list[Optional[int]]]) -> bool:
    if not len(board) or not all(len(row) == len(board) for row in board):
        raise ValueError('Invalid board, must be square.')
    board_rows, board_cols = len(board), len(board[0])
    if len(position) != 2:
        raise ValueError('Position must have exactly two values.')
    row, col = position
    if 0 <= row < board_rows and 0 <= col < board_cols:
        return board[row][col] is None
    raise ValueError('Position must be on board.')


def main() -> None:
    board = [
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 1, 2, 3],
        [4, 5, 6, None],
    ]
    print(is_none((0, 0), board))
    print(is_none((3, 3), board))


if __name__ == '__main__':
    main()

Output:

False
True
Answer from Sash Sinha on Stack Overflow
Top answer
1 of 1
1

You can use a list comprehension.

array = [[False for _ in range(n)] for _ in range(n)]

See here:

>>> from pprint import pprint
>>> n = 10
>>> array = [[False for _ in range(n)] for _ in range(n)]
>>> pprint(array)
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]

Now if you want to change an element at (i, j), you can just assign to it:

>>> array[2][4] = True
>>> pprint(array)

[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, True, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
Top answer
1 of 3
3

I just typed up something quickly, maybe you get an idea from here

from datetime import datetime, date
# stores each time fram between pickup and dropoff
time = []
# inits a global counter, that is updated dependend on you array
counter = 0
# inits global time constants that are updated, based on logic
starttime = datetime(2009, 10, 5, 18, 0)
endtime = datetime(2009, 10, 5, 18, 0)

for i in range(len(s)):
    # check if initial pickup, if 0 that means inital pickup, therefore update time
    if(counter == 0):
        starttime = datetime.strptime(s[i][1],'%Y-%m-%d %H:%M:%S')
    # in case pickup add 1 to counter to indicate the number of packages on hand
    if(s[i][2] == 'pickup'):
        counter = counter + 1
    # in case dropoff subtract 1 from counter to update packages on hand
    else:
        counter = counter - 1
    # in case counter reaches 0 meaning no more packages, therefore measure time differences
    if(counter == 0):
        endtime = datetime.strptime(s[i][1],'%Y-%m-%d %H:%M:%S')
        print(endtime - starttime)
        time.append(endtime - starttime)
2 of 3
1

Try the below code:

from datetime import datetime

def calculateTime(frm, to):
    p = '%Y-%m-%d %H:%M:%S'
    epoch = datetime(1970, 1, 1)
    frmTime = (datetime.strptime(frm, p) - epoch).total_seconds()
    toTime = (datetime.strptime(to, p) - epoch).total_seconds()
    return toTime - frmTime

def printTime(t, form='H:M'):
    h = int(t/(60*60))
    m = int(60 * (t/(60*60) - h))
    s = int(t - ((h * 60 * 60) + (m * 60)))
    if form == 'H:M':
        print h,'hrs ',m,'mins'
    if form == 'H:M:S':
        print h,'hrs ',m,'mins',s,' secs'
#changed
def totalActiveTime(lst):
    orders = []
    activeTime = 0
    prevTime = None
    for i in lst:
        if i[2] == 'pickup':
            orders.append(i[0])
            if prevTime == None:
                prevTime = i[1]
        elif i[2] == 'dropoff':
            orders.remove(i[0])
            if len(orders) == 0:
                activeTime += calculateTime(prevTime, i[1])
                prevTime = None
    return activeTime
s = [

    [1, '2017-08-15 13:30:00', 'pickup'],

    [1, '2017-08-15 14:00:00', 'dropoff'],

    [2, '2017-08-15 14:30:00', 'pickup'],

    [3, '2017-08-15 14:35:00', 'pickup'],

    [2, '2017-08-15 15:00:00', 'dropoff'],

    [4, '2017-08-15 15:05:00', 'pickup'],

    [3, '2017-08-15 15:10:00', 'dropoff'],

    [4, '2017-08-15 15:40:00', 'dropoff'],

]
printTime(totalActiveTime(s))

Output

1 hrs  40 mins
Top answer
1 of 4
3

finalList is always an empty list on your list-comprehension even though you think it's appending during that to it, which is not the same exact case as the second code (double for loop).

What I would do instead, is use set:

>>> set(i for sub_l in x for i in sub_l)
{1, 2, 3}

EDIT: Otherway, if order matters and approaching your try:

>>> final_list = []
>>> x_flat = [i for sub_l in x for i in sub_l]
>>> list(filter(lambda x: f.append(x) if x not in final_list else None, x_flat))
[] #useless list thrown away and consumesn memory
>>> f
[1, 2, 3]

Or

>>> list(map(lambda x: final_list.append(x) if x not in final_list else None, x_flat))
[None, None, None, None] #useless list thrown away and consumesn memory
>>> f
[1, 2, 3]

EDIT2: As mentioned by timgeb, obviously the map & filter will throw away lists that are at the end useless and worse than that, they consume memory. So, I would go with the nested for loop as you did in your last code example, but if you want it with the list comprehension approach than:

>>> x_flat = [i for sub_l in x for i in sub_l]
>>> final_list = []
>>> for number in x_flat:
        if number not in final_list:
            finalList.append(number)
2 of 4
1

The expression on the right-hand-side is evalueated first, before assigning the result of this list comprehension to the finalList. Whereas in your second approach you write to this list all the time between the iterations. That's the difference.

That may be similar to the considerations why the manuals warn about unexpected behaviour when writing to the iterated iterable inside a for loop.

you could use the built-in set()-method to remove duplicates (you have to do flatten() on your list before)

Find elsewhere
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 52376325 โ€บ shuffle-a-2d-list-in-python
Shuffle a 2d list in python - Stack Overflow
September 18, 2018 - Releases Keep up-to-date on features we add to Stack Overflow and Stack Internal. ... Find centralized, trusted content and collaborate around the technologies you use most. Learn more about Collectives ... Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... I am new to Python. I have a Python 2D array [[a,b,c],[d,e,f],[g,h,j]] and would like to shuffle the 3 inner lists ...
Top answer
1 of 2
3

multiplying a single reference data type would simply create multiple references of the same type. What it means is that [True]*N is actually N times the same instance of the element [True]

Thus changing one would inadvertently change the others

As you can see in the following example,

>>> grid = [[True]]*10
>>> grid = [True]*10
>>> [id(e) for e in grid]
[505379788, 505379788, 505379788, 505379788, 505379788, 505379788, 505379788, 505379788, 505379788, 505379788]

It shows all the elements are actually the same instance.

But because here as the element is not a mutable Type, changing won't be an issue here as, changing one of the element would simply assign a new instance.

Problem happens with a mutable type

>>> [id(e) for e in grid]
[66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744]
>>> grid[0][0]=False
>>> [id(e) for e in grid]
[66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744]
>>> grid
[[False], [False], [False], [False], [False], [False], [False], [False], [False], [False]]

To get over it, you need to understand which are mutable types and refrain from duplicating it but instead create new multiple instances of the same mutable types

So here as a list is a mutable type, you need to create multiple instances, possibly through list comprehension

[[False]*N for _ in range(N)]
2 of 2
2

Much like this question, you're lists are in fact pointing to the same list. Instead, define your list as:

[[False] * N for i in xrange(N)]

Or in Python 3:

[[False] * N for i in range(N)]

Then modifying one element will modify only that element.

Note the Python 3 range function also works in Python 2 - however in Python 2 the range function returns a list, as opposed to a range object in Python 3, and the xrange object of Python 2, both of which are iterators.

Top answer
1 of 7
9

You haven't declared ar yet. In Python, you don't have to perform separate declaration and initialization; nevertheless, you can't perform operations on names willy-nilly.

Start off with something like this:

ar = [[0 for j in range(m)] for i in range(n)]
2 of 7
2

You should know that ar is not defined when you are trying to perform an assignment like ar[i][j] = int(input()), there are many ways to fix that.

In C/C++

In C/C++, I presume you would do such work like this:

#include <cstdio>

int main()
{
    int m, n;
    scanf("%d %d", &m, &n);
    int **ar = new int*[m];
    for(int i = 0; i < m; i++)
        ar[i] = new int[n];
    for(int i = 0; i < m; i++)
        for(int j = 0; j < n; j++)
            scanf("%d", &ar[i][j]);
    // Do what you want to do
    
    for(int i = 0; i < m; i++)
        delete ar[i];
    delete ar;
   
    return 0;
}

Before you get inputs by scanf in C/C++, you should allocate storage by calling new or malloc, then you can perform your scanf, or it will crash.

How to do like that in Python

It's very similar to what you had done in C/C++, according to your code, when you are trying to perform assignment to ar[i][j], Python has no idea what ar it is! So you have to let it know first.

A NOT-pythonic way

A NOT-Pythonic way is do something like you did in C/C++:

n = int(input())
m = int(input())

ar = []
for i in range(m):
    ar.append([])
    for j in range(n):
        k = int(input())
        ar[i].append(k)

for i in range(m):
    for j in range(n):
        print(ar[i][j])

You initialize the list by ar = [] like you did int **ar = new int*[m]; in C/C++. For each row in the 2-d list, initialize the row by using ar.append([]) like you did ar[i] = new int[n]; in C/C++. Then, get your data by using input and append it to ar[i].

A pythonic way

The way to perform such a job like above it's not very pythonic, instead, you can get it done by using a feature called List Comprehensions, then the code can be simplified into this:

n = int(input())
m = int(input())

ar = [[0 for j in range(n)] for i in range(m)]
for i in range(m):
    for j in range(n):
        k = int(input())
        ar[i][j] = k

for i in range(m):
    for j in range(n):
        print(ar[i][j])

Note that the core ar = [[0 for j in range(n)] for i in range(m)] is a list comprehension that it creates a list which has m lists and for each list of these m lists it has n 0s.

๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 18563680 โ€บ how-to-sort-a-2d-list
python - How to sort a 2D list? - Stack Overflow
I have following type of list lst = [ [1, 0.23], [2, 0.39], [4, 0.31], [5, 0.27], ] I want to sort this in descending order of the second column. I tried built-in sorted() function...