Как вы сравниваете числовые интервалы, записанные в виде строк, в Python?

#python #module #intervals

#python #модуль #интервалы

Вопрос:

Для этого файла данных, с которым я работаю, мне даны пары списков, где каждый элемент представляет возрастной интервал, но они записаны в виде строк. Например,

List1 = ['0-9', '10-19', '20-29', '30-39', '40-49', '50-']

List2 = ['0-19', '20-39', '40-']

List1 используется в качестве шаблона для представления возрастных интервалов для соответствующих данных:

A1 = [30, 40, 50, 60, 70, 80]

B1 = [33, 20, 40, 76, 777, 844]

Так, например, второй элемент A1 означает, что значение равно 40 для возрастного интервала ’10-19′, пятый элемент B1 означает, что значение равно 777 для интервала ’40-49′.

Из-за совпадения временных интервалов в List1 со List2 можно суммировать элементы в A1 и B1, чтобы они теперь представляли временной интервал List2.

A2 = [70, 110, 150]

B2 = [53, 116, 1621]

Итак, теперь, например, второй элемент A2 (ранее A1) представляет значение 110 для возрастного интервала ’20-39′, а первый элемент B2 (ранее B2) представляет 53 для интервала ‘0-19’.

Данные для List1 были переназначены, чтобы соответствовать возрастным интервалам List2. Это возможно из-за перекрывающихся возрастных интервалов. Это невозможно сделать для данных, представляющих следующие два возрастных интервала:

List3 = ['0-14', '15-29', '30-44', '45-']

List4 = ['0-19', '20-39', '40-']

Из-за формата данных я не знаю, как я могу проверить, имеют ли два списка перекрывающиеся возрастные интервалы, что позволяет повторно объединять данные для представления нового набора возрастных интервалов. Если бы кто-нибудь мог указать мне метод или библиотеку, доступные в python, которые способны сделать такую задачу возможной, в частности, для работы с числовыми интервалами, представленными в виде строк, это было бы очень ценно. Спасибо.

Комментарии:

1. Вы можете разделить '0-9' на ('0', '9') by '0-9'.split('-') . Это может быть вашей отправной точкой. Но я не понимаю правила проверки вашей ситуации. Можете ли вы объяснить детали?

2. Спасибо за ваш комментарий. Я попытаюсь объяснить детали немного более четко: каждый список содержит возрастные интервалы, как показано выше. Однако для каждого из представленных мной списков привязан другой список с данными для соответствующих возрастных интервалов. Поскольку элементы List1 могут быть суммированы таким образом, чтобы представлять возрастные интервалы Lists2, другой набор данных для List1 также может быть суммирован, чтобы соответствовать возрастным интервалам List2. List3 и List4 представляют случай, когда невозможно повторно связать другие данные из этих списков.

3. «если элементы List1 могут быть суммированы для представления List2». Я не понимаю, что это значит. Какова основная логика здесь?

4. @BoseongChoi я обновил свой вопрос. Если кому-то все еще не ясно, пожалуйста, дайте мне знать. Спасибо.

5. @KarlKnechtel Пожалуйста, дайте мне знать, если вопрос теперь ясен. Спасибо.

Ответ №1:

Мы можем использовать split метод для перехода от '0-9' к ('0', '19') . Применение этого метода ко всем парам может выглядеть следующим образом:

 list1 = [s.split('-') for s in list1]
list2 = [s.split('-') for s in list2]
  

Теперь нам нужно выполнить итерацию list1 , чтобы объединить пары два на два.
Для этого я использовал zip функцию.

 merge = [[pair[0][0], pair[1][1]] for pair in list(zip(list1,list1[1:]))[::2]]
  

Затем нам нужно только сравнить наш новый merge список с list2 .

 merge == list2
  

Все вместе:

 def foo(list1, list2):
    list1 = [s.split('-') for s in list1]
    list2 = [s.split('-') for s in list2]
    merge = [[pair[0][0], pair[1][1]] for pair in list(zip(list1,list1[1:]))[::2]]
    return merge == list2

print(foo(List1, List2)) # True
print(foo(List3, List4)) # False
  

Комментарии:

1. не нужно преобразовывать в int. не нужно преобразовывать в кортежи: list1 = [s.split('-') for s in list1] \ list2 = [s.split('-') for s in list2] \ merge = [[pair[0][0], pair[1][1] if pair[1][1] else ''] for pair in list(zip(list1,list1[1:]))[::2]] \ return merge == list2

2. Действительно! Я потерял себя, пытаясь суммировать пары в какой-то момент моего исследования… Спасибо, что указали на это! Я отредактировал свой ответ

3. А затем также можно удалить if else в merge = [[pair[0][0], pair[1][1]] for pair in list(zip(list1,list1[1:]))[::2]]

4. Еще раз хороший улов!

Ответ №2:

Вы можете отсортировать все младшие возрасты в одном наборе и все старшие возрасты в другом наборе. Затем посмотрите, существует ли все более старые возрасты более короткого списка в более старом из более длинного списка и то же самое для младшего. Таким образом, он будет соответствовать не только парам, но и любой комбинации синглов, пар, триплетов и т. Д.

 def can_represent(short_list, long_list):
    youngs_1 = {s.split('-')[0] for s in short_list}
    youngs_2 = {s.split('-')[0] for s in long_list}
    olds_1 = {s.split('-')[1] for s in short_list}
    olds_2 = {s.split('-')[1] for s in long_list}
    return not youngs_1 - youngs_2 and not olds_1 - olds_2
  

Комментарии:

1. Спасибо за ваш ответ, Джолбас, мне нравится этот альтернативный подход

2. @user9977 Эта функция возвращает true, если существуют и другие комбинации возрастных диапазонов, кроме пар. Например 0-9, 10-19, 20-29, 30-39, 40- матчи 0-9, 10-39, 40-