Смущает преобразование цикла for в карту, которое дает разные результаты.Python

Программы на Python
Ответить
Anonymous
 Смущает преобразование цикла for в карту, которое дает разные результаты.

Сообщение Anonymous »

У меня есть существующая реализация функции, использующая цикл for.
Я хочу преобразовать ее в более функциональную форму с помощью операции сопоставления .
Моя текущая рабочая реализация
Это функция, которую я хочу преобразовать:
def _fast_scandir_3_impl_get_paths_recursive(target: str) -> list[str]:
items:list[str] = []
if os.path.isfile(target):
items.append(target)
elif os.path.isdir(target):
items.append(target)
for item in os.listdir(target):
item = os.path.join(target, item)
more_items = _fast_scandir_3_impl_get_paths_recursive(item)
items.extend(more_items)
return items

Моя попытка преобразовать эту функцию, но она не работает
Это моя попытка преобразовать ее.
def _fast_scandir_3_impl_get_paths_recursive(target: str) -> list[str]:
items:list[str] = []
if os.path.isfile(target):
items.append(target)
elif os.path.isdir(target):
items.append(target)
items.extend(
map(
_fast_scandir_3_impl_get_paths_recursive,
map(
lambda item: os.path.join(target, item),
os.listdir(target),
)
)
)
return items

Моя структура тестового каталога:
Это понадобится вам для воспроизводимости.
example-target-directory/
example-file.txt
example/subdir/
example-file-2.txt

Вывод
Эти выходные данные были получены исходным кодом. Это то, что мы ожидаем от второй версии функции.
running fast_scandir_3(example-target-directory)
results:
('d', '/home/user/work/python/example-target-directory')
('f', '/home/user/work/python/example-target-directory/example-file.txt')
('d', '/home/user/work/python/example-target-directory/example-subdir')
('f', '/home/user/work/python/example-target-directory/example-subdir/example-file-2.txt')

Новая версия кода вызывает исключение при вызове функции _fast_scandir_3_impl_convert_paths_to_path_tuples.
Тестовый пример 1import os

def _fast_scandir_3_impl_convert_paths_to_path_tuples(paths:list[str]) -> list[tuple[str, str]]:
def path_to_tuple(path:str) -> tuple[str, str]:
if os.path.isfile(path):
return ('f', path)
elif os.path.isdir(path):
return ('d', path)

return (
list(
map(
path_to_tuple,
paths,
)
)
)

def _fast_scandir_3_impl_get_paths_recursive(target: str) -> list[str]:
items:list[str] = []
if os.path.isfile(target):
items.append(target)
elif os.path.isdir(target):
items.append(target)
for item in os.listdir(target):
item = os.path.join(target, item)
more_items = _fast_scandir_3_impl_get_paths_recursive(item)
items.extend(more_items)
return items

print(_fast_scandir_3_impl_get_paths_recursive('example-target-directory'))

print(
_fast_scandir_3_impl_convert_paths_to_path_tuples(
_fast_scandir_3_impl_get_paths_recursive('example-target-directory')
)
)

Они печатают разные вещи:
# Test Case 1
user@host:~/work/python$ python3 test1.py
['example-target-directory', 'example-target-directory/example-subdir', 'example-target-directory/example-subdir/example-file-2.txt', 'example-target-directory/example-file.txt']
[('d', 'example-target-directory'), ('d', 'example-target-directory/example-subdir'), ('f', 'example-target-directory/example-subdir/example-file-2.txt'), ('f', 'example-target-directory/example-file.txt')]

# Test Case 2
user@host:~/work/python$ python3 test2.py
['example-target-directory', ['example-target-directory/example-subdir', ['example-target-directory/example-subdir/example-file-2.txt']], ['example-target-directory/example-file.txt']]
Traceback (most recent call last):
File "test2.py", line 40, in
_fast_scandir_3_impl_convert_paths_to_path_tuples(
File "test2.py", line 12, in _fast_scandir_3_impl_convert_paths_to_path_tuples
list(
File "test2.py", line 6, in path_to_tuple
if os.path.isfile(path):
^^^^^^^^^^^^^^^^^^^^
File "", line 30, in isfile
TypeError: stat: path should be string, bytes, os.PathLike or integer, not list

Тестовый пример 2
import os

def _fast_scandir_3_impl_convert_paths_to_path_tuples(paths:list[str]) -> list[tuple[str, str]]:
def path_to_tuple(path:str) -> tuple[str, str]:
if os.path.isfile(path):
return ('f', path)
elif os.path.isdir(path):
return ('d', path)

return (
list(
map(
path_to_tuple,
paths,
)
)
)

def _fast_scandir_3_impl_get_paths_recursive(target: str) -> list[str]:
items:list[str] = []
if os.path.isfile(target):
items.append(target)
elif os.path.isdir(target):
items.append(target)
items.extend(
map(
_fast_scandir_3_impl_get_paths_recursive,
map(
lambda item: os.path.join(target, item),
os.listdir(target),
)
)
)
return items

print(_fast_scandir_3_impl_get_paths_recursive('example-target-directory'))

print(
_fast_scandir_3_impl_convert_paths_to_path_tuples(
_fast_scandir_3_impl_get_paths_recursive('example-target-directory')
)
)

Вы должны обнаружить, что первый оператор print печатает вложенный набор списков, а не один список. Если вы не заметили такого поведения, значит что-то не так.
  • Я не могу понять, почему эта функция возвращает список списков, а не просто списка.
Дополнительная информация: карта работает как положено
  • Кто-то в комментариях предположил, что множественные вызовы Map создают вложенные итераторы, но я не найти такого поведения. Этот код создает один список без вложенных списков.
result = (
list(
map(
lambda x: x + 1,
map(
lambda x: x + 2,
map(
lambda x: x + 3,
[1, 2, 3, 4, 5],
)
)
)
)
)

print(result) # [7, 8, 9, 10, 11]


Подробнее здесь: https://stackoverflow.com/questions/792 ... nt-results
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»