Форум программистов, компьютерный форум, киберфорум
iamvic
Войти
Регистрация
Восстановить пароль
Путевые заметки в процессе познания Python и PyQt/PySide.
Помни - только тег CODE не портит код добавлением пробела в начало пустой строки.
Оценить эту запись

К вопросу о транспонировани­­и...

Запись от iamvic размещена 09.09.2024 в 15:14
Метки python 3

Просто оставлю это здесь в качестве памятки. Заниматься-то транспонированием приходится крайне редко, а тут такой интересный эффект обнаружился с транспонированием списка строк (смотри К вопросу о построении дерева родительских отношений в PyQt (часть 4)). Прямого упоминания о такой возможности я как-то даже и не нашёл (видимо, считается само собой разумеющимся, а для меня оказалось сюрпризом).

Пошарив по Интернету, надёргал разных решений (каждый может узнать своё ) и налепил демонстратор:

transposer.py:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
print('1. T is original matrix')
T = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9],
     [10, 11, 12]]
print('T =', T)
for i in T:
    print(*i)
 
print()
print('2. T1 is transposed matrix T (variant NOVICE)')
print('T =', T)
T1 = list()
for i in range(len(T[0])):
    T1.append(list())
    for j in range(len(T)):
        T1[i].append(T[j][i])
print('T1 =', T1)
for i in T1:
    print(*i)
 
print()
print('3. T2 is transposed matrix T (variant WORKER)')
print('T =', T)
T2 = [[T[j][i] for j in range(len(T))] for i in range(len(T[0]))]
print('T2 =', T2)
for i in T2:
    print(*i)
 
print()
print('4. T3 is transposed matrix T (variant MAP)')
print('T =', T)
T3 = list(map(lambda *x: list(x),*T))
print('T3 =', T3)
for i in T3:
    print(*i)
 
print()
print('5. T4 is transposed matrix T (variant ZIP)')
print('T =', T)
T4 = list(zip(*T))
print('T4 =', T4)
for i in T4:
    print(*i)
 
print()
print('6. T5 is transposed matrix T (variant NUMPY)')
print('T =', T)
import numpy
T5 = numpy.transpose(numpy.array(T))
print('T5 =', T5)
for i in T5:
    print(*i)
 
print()
print('7. S is original list of strings')
S = ['abc',
     'def',
     'ghi',
     'jkl']
print('S =', S)
for i in S:
    print(*i)
 
print()
print('8. S1 is transposed list of strings S (variant NOVICE)')
print('S =', S)
S1 = list()
for i in range(len(S[0])):
    S1.append(list())
    for j in range(len(S)):
        S1[i].append(S[j][i])
print('S1 =', S1)
for i in S1:
    print(*i)
 
print()
print('9. S2 is transposed list of strings S (variant WORKER)')
print('S =', S)
S2 = [[S[j][i] for j in range(len(S))] for i in range(len(S[0]))]
print('S2 =', S2)
for i in S2:
    print(*i)
 
print()
print('10. S3 is transposed list of strings S (variant MAP)')
print('S =', S)
S3 = list(map(lambda *x: list(x),*S))
print('S3 =', S3)
for i in S3:
    print(*i)
 
print()
print('11. S4 is transposed list of strings S (variant ZIP)')
print('S =', S)
S4 = list(zip(*S))
print('S4 =', S4)
for i in S4:
    print(*i)
 
print()
print('12. S5 is transposed list of strings S (variant NUMPY)')
print('S =', S)
import numpy
S5 = numpy.transpose(numpy.array(S))
print('S5 =', S5)
for i in S5:
    print(*i)


А вот результаты интересные:
1. numpy автоиммунен к транспонированию списка строк (тупо ничего не делает),
2. sympy валится в ошибки (даже не буду приводить пример),
3. а остальные бодро транспонируют список строк в матрицу, не смотря на очевидную разницу в подходах:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
user@linux:~/projects/probe> python3 transposer.py
1. T is original matrix
T = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
1 2 3
4 5 6
7 8 9
10 11 12
 
2. T1 is transposed matrix T (variant NOVICE)
T = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
T1 = [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
1 4 7 10
2 5 8 11
3 6 9 12
 
3. T2 is transposed matrix T (variant WORKER)
T = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
T2 = [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
1 4 7 10
2 5 8 11
3 6 9 12
 
4. T3 is transposed matrix T (variant MAP)
T = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
T3 = [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
1 4 7 10
2 5 8 11
3 6 9 12
 
5. T4 is transposed matrix T (variant ZIP)
T = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
T4 = [(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)]
1 4 7 10
2 5 8 11
3 6 9 12
 
6. T5 is transposed matrix T (variant NUMPY)
T = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
T5 = [[ 1  4  7 10]
 [ 2  5  8 11]
 [ 3  6  9 12]]
1 4 7 10
2 5 8 11
3 6 9 12
 
7. S is original list of strings
S = ['abc', 'def', 'ghi', 'jkl']
a b c
d e f
g h i
j k l
 
8. S1 is transposed list of strings S (variant NOVICE)
S = ['abc', 'def', 'ghi', 'jkl']
S1 = [['a', 'd', 'g', 'j'], ['b', 'e', 'h', 'k'], ['c', 'f', 'i', 'l']]
a d g j
b e h k
c f i l
 
9. S2 is transposed list of strings S (variant WORKER)
S = ['abc', 'def', 'ghi', 'jkl']
S2 = [['a', 'd', 'g', 'j'], ['b', 'e', 'h', 'k'], ['c', 'f', 'i', 'l']]
a d g j
b e h k
c f i l
 
10. S3 is transposed list of strings S (variant MAP)
S = ['abc', 'def', 'ghi', 'jkl']
S3 = [['a', 'd', 'g', 'j'], ['b', 'e', 'h', 'k'], ['c', 'f', 'i', 'l']]
a d g j
b e h k
c f i l
 
11. S4 is transposed list of strings S (variant ZIP)
S = ['abc', 'def', 'ghi', 'jkl']
S4 = [('a', 'd', 'g', 'j'), ('b', 'e', 'h', 'k'), ('c', 'f', 'i', 'l')]
a d g j
b e h k
c f i l
 
12. S5 is transposed list of strings S (variant NUMPY)
S = ['abc', 'def', 'ghi', 'jkl']
S5 = ['abc' 'def' 'ghi' 'jkl']
a b c
d e f
g h i
j k l

Всем спасибо!
Размещено в Памятка
Показов 1216 Комментарии 8
Всего комментариев 8
Комментарии
  1. Старый комментарий
    Аватар для AlexProgramm
    Отличная транспортировка
    Запись от AlexProgramm размещена 10.09.2024 в 11:55 AlexProgramm вне форума
  2. Старый комментарий
    AlexProgramm, спасибо за поддержку

    Мне тут молодёжь моя уже высказалась, что наконец-то найден самый питонистый из пропитоньевых способов преобразования списка строк одинаковой длины в матрицу. Даже сляпали функцию соответствующую

    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    def los2mat(x):
        '''los2mat(x) - convert x (as list of strings) to matrix'''
        y = [[x[j][i] for j in range(len(x))] for i in range(len(x[0]))]
        return [[y[j][i] for j in range(len(y))] for i in range(len(y[0]))]
     
    if __name__ == '__main__':
        z = ['Один 1',
             'Zwei 2',
             'Пять 5',
             'Сinque']
        print(los2mat(z))

    Ну, не может же быть такого, чтобы этот момент был упущен. Питону уж столько лет, что все эти особенности должны были бы быть выявлены и документированы. Но я никак не могу найти прямого указания на такую возможность. Да и времени-то особо нет, чтобы заниматься этим.
    Запись от iamvic размещена 11.09.2024 в 14:12 iamvic вне форума
  3. Старый комментарий
    Выглядит страшновато

    Как устроен питон и сколько раз будет вызвано, например, range(len(x)) ?
    Запись от voral размещена 12.09.2024 в 13:57 voral вне форума
  4. Старый комментарий
    PHP
    1
    2
    3
    
    <?php
    $z = ['Один 1', 'Zwei 2', 'Пять 5', 'Сinque'];
    print_r(array_map('mb_str_split', $z));
    Хотя, у меня не полный аналог - в моем варианте строки могут быть разной длины. Но тут просто mb_str_split вынести в функцию, в которой еще (если по аналогии с вашим кодом) обрезать по количеству символов в первой строке.
    Запись от voral размещена 12.09.2024 в 14:09 voral вне форума
    Обновил(-а) voral 12.09.2024 в 14:12
  5. Старый комментарий
    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    def los2mat(x):
        '''los2mat(x) - convert x (as list of strings) to matrix'''
        result = []
        for item in x:
            result.append([oneChar for oneChar in item])
        return result;
     
    if __name__ == '__main__':
        z = ['Один 1',
             'Zwei 2',
             'Пять 5',
             'Сinque']
        print(los2mat(z))
    Запись от voral размещена 12.09.2024 в 14:19 voral вне форума
  6. Старый комментарий
    Еще поиздевался над вашим питоном
    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    def los2mat(x):
        '''los2mat(x) - convert x (as list of strings) to matrix'''
        return [[oneChar for oneChar in item] for item in x];
     
    if __name__ == '__main__':
        z = ['Один 1',
             'Zwei 2',
             'Пять 5',
             'Сinque']
        print(los2mat(z))
    Запись от voral размещена 12.09.2024 в 14:25 voral вне форума
  7. Старый комментарий
    Цитата:
    Еще поиздевался над вашим питоном
    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    def los2mat(x):
        '''los2mat(x) - convert x (as list of strings) to matrix'''
        return [[oneChar for oneChar in item] for item in x];
     
    if __name__ == '__main__':
        z = ['Один 1',
             'Zwei 2',
             'Пять 5',
             'Сinque']
        print(los2mat(z))
    voral, дружище, инерция мышления имеет место быть, грешен. Но тут дело несколько хуже обстоит, соберусь с мыслями обрисую...
    Запись от iamvic размещена 17.09.2024 в 16:12 iamvic вне форума
  8. Старый комментарий
    voral, ещё раз спасибо огромное за подсказки, мне хоть удалось понять, что на самом деле надо было подкрутить в первую очередь... Ваш намёк на обработку строк разной длины оказался решающим аргументом. Решение может быть выглядит в моём исполнении неказисто, но зато существенно облегчает обратную операцию - сброку списка строк из матрицы. Плюс не надо выравнивать исходные строки по длине с помощью символа-заполнителя, что было весьма рискованно.

    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    def los2mat(x):
        '''los2mat(x) - convert x (as list of strings) to matrix'''
        l_max = 0
        for item in x:
            l_max = len(item) if l_max < len(item) else l_max
        result = []
        for item in x:
            result.append([oneChar for oneChar in item])
        for ix in result:
            l_ix = len(ix)
            if l_max > l_ix:
                for t in range(l_max - l_ix):
                    ix.append('')
        return result
     
    if __name__ == '__main__':
        z = ['Один 1',
             'Zwei 22',
             'Пять 55555',
             'Сinque']
        print(los2mat(z))
    Запись от iamvic размещена 22.09.2024 в 19:04 iamvic вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru