Python中的数字表操作

2024-09-30 16:30:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我想对digram列表进行添加/替换,它类似于:

[[a,b][b,c][c,d][d,c][c,b][b,a]]

如果列表被展平,结果将是:´´[a,b,c,d,c,b,a]´´,但这只是描述结构,而不是问题。你知道吗

Note that there are only two items on a digram and each of the two items on a digram precedes the next and the previous digram items, except of the first and the last digram, where terminating item occurs only once. See item ´´a´´.

我的问题是,如何将digrams替换到列表中,以便注释部分的下一个示例结果能够实现:

replace([['d','d']],          1, ['a', 0]) # should return: [['d', 'd']]
replace([['d',1]],            1, ['a', 0]) # should return: [['d', 'a'], ['a', 0]]
replace([[1,'d']],            1, ['a', 0]) # should return: [['a', 0], [0, 'd']]
replace([[1,'d'],['d', 1]],   1, ['a', 0]) # should return: [['a', 0], [0, 'd'], ['d', 'a'], ['a', 0]]
replace([['d',1],[1,'d']],    1, ['a', 0]) # should return: [['d','a'], ['a', 0], [0, 'd']]
replace([[1,1]],              1, ['a', 0]) # should return: [['a', 0], [0, 'a'], ['a', 0]]
replace([[1,1],[1,1]],        1, ['a', 0]) # should return: [['a', 0], [0, 'a'], ['a', 0], [0, 'a'], ['a', 0]]

我试过下一种方法,但有一些问题。尤其是´´j==1´´下的零件有不起作用的特殊情况。你知道吗

def replace(t, a, b):
    """
    1. argument is the target list
    2. argument is the index value to be used on replacement
    3. argument is the digram to be inserted
    """
    # copy possibly not needed, im not sure
    t1 = t[:]
    for i, x in enumerate(t1):
        for j, y in enumerate(x):
            # if there is a digram match, lets make replacement / addition
            if y == a:
                if j == 0:
                    c = t1[i:]
                    del t1[i:]
                    t1 += [b] + c
                    c[0][0] = b[1]
                if j == 1:
                    c = t1[i:]
                    del t1[i:]
                    t1 += c + [b]
                    c[len(c)-1][1] = b[0]
                    #c[0][1] = b[0]
                    #t1 += c

    print (t, t1)

你能提出一些改进功能的建议吗?或者有其他方法来完成这个任务吗?你知道吗

加法

这是我的加密版本的功能,它提供了正确的答案,但仍然“恼人”的一部分或整个方法可以优化。这个问题和主题可以更多地转到代码优化领域:

def replace(t, a, b):
    """
    1. argument is the target list
    2. argument is the index value to be used on replacement
    3. argument is the digram to be inserted
    """
    l = len(t)
    i = 0
    while i < l:
        for j, y in enumerate(t[i]):
            # if there is a digram match, lets make replacement / addition
            if y == a:
                if j == 0:
                    c = t[i:]
                    del t[i:]
                    t += [b] + c
                    c[0][0] = b[1]
                    # increase both index and length
                    # this practically jumps over the inserted digram to the next one
                    i += 1
                    l += 1
                elif j == 1:
                    c = t[i:]
                    del t[i:]
                    # this is the annoying part of the algorithm...
                    if len(c) > 1 and c[1][0] == a:
                        t += c
                    else:
                        t += c + [b]
                        c[-1][1] = b[0]
                    t[i][1] = b[0]
        i += 1

    return t

我还提供测试功能来测试输入和输出:

def test(ins, outs):
    try:
        assert ins == outs
        return (True, 'was', outs)
    except:
        return (False, 'was', ins, 'should be', outs)

for i, result in enumerate(
    [result for result in [
[replace([['d','d']],          1, ['a', 0]), [['d', 'd']]],
[replace([['d',1]],            1, ['a', 0]), [['d', 'a'], ['a', 0]]],
[replace([[1,'d']],            1, ['a', 0]), [['a', 0], [0, 'd']]],
[replace([[1,'d'],['d', 1]],   1, ['a', 0]), [['a', 0], [0, 'd'], ['d', 'a'], ['a', 0]]],
[replace([['d',1],[1,'d']],    1, ['a', 0]), [['d','a'], ['a', 0], [0, 'd']]],
[replace([[1,1]],              1, ['a', 0]), [['a', 0], [0, 'a'], ['a', 0]]],
[replace([[1,1],[1,1]],        1, ['a', 0]), [['a', 0], [0, 'a'], ['a', 0], [0, 'a'], ['a', 0]]],
[replace([['d',1],[1,1]],      1, ['a', 0]), [['d', 'a'], ['a', 0], [0, 'a'], ['a', 0]]],
[replace([[1,1],[1,'d']],      1, ['a', 0]), [['a', 0], [0, 'a'], ['a', 0], [0, 'd']]]
]]):
    print (i+1, test(*result))

Tags: andthetoinforreturnifis
1条回答
网友
1楼 · 发布于 2024-09-30 16:30:20

这是我的方法。解释如下。你知道吗

def replace(t, a, b):
    # Flatten the list
    t = [elem for sub in t for elem in sub]
    replaced = []
    # Iterate the elements of the flattened list
    # Let the elements that do not match a in and replace the ones that
    # do not match with the elements of b
    for elem in t:
        if elem == a:  # this element matches, replace with b
            replaced.extend(b)
        else:          # this element does not, add it
            replaced.append(elem) 
    # break up the replaced, flattened list with groups of 2 elements
    return [replaced[x:x+2] for x in range(len(replaced)-1)]

你从一些列表开始。所以首先,我们可以把它展平。你知道吗

[[1,'d'],['d', 1]] becomes [1,'d','d', 1]

现在我们可以循环遍历展平列表,在a上找到匹配项的任何地方,我们都可以用b的内容扩展replaced列表。如果元素与a不匹配,我们只需将其附加到replaced。我们的结局是:

['a', 0, 'd', 'd', 'a', 0]

现在我们要把所有这些都分成两组,一次移动索引1。你知道吗

[['a', 0] ...]
[['a', 0], [0, 'd'], ...]
[['a', 0], [0, 'd'], ['d', 'd'], ...]

如果您的数据比示例长得多,并且需要改进性能,那么可以删除列表的展平,并且可以使用嵌套循环展平t中的值,这样就可以通过t进行单次传递。你知道吗

编辑

def replace(t, a, b):
    t = [elem for sub in t for elem in sub]

    inner_a_matches_removed = []
    for i, elem in enumerate(t):
        if not i % 2 or elem != a:
            inner_a_matches_removed.append(elem)
            continue
        if i < len(t) - 1 and t[i+1] == a:
            continue
        inner_a_matches_removed.append(elem)

    replaced = []
    for elem in inner_a_matches_removed:
        if elem == a:
            replaced.extend(b)
        else:
            replaced.append(elem)
    return [replaced[x:x+2] for x in range(len(replaced)-1)]

这里还有一个附加测试:

args_groups = [
        ([['d','d']],          1, ['a', 0]),
        ([['d',1]],            1, ['a', 0]),
        ([[1,'d']],            1, ['a', 0]),
        ([[1,'d'],['d', 1]],   1, ['a', 0]),
        ([['d',1],[1,'d']],    1, ['a', 0]),
        ([[1,1]],              1, ['a', 0]),
        ([[1,1],[1,1]],        1, ['a', 0]),
]

for args in args_groups:
    print "replace({}) => {}".format(", ".join(map(str, args)), replace(*args))

输出:

replace([['d', 'd']],             1,   ['a', 0]) => [['d', 'd']]
replace([['d', 1]],               1,   ['a', 0]) => [['d', 'a'], ['a', 0]]
replace([[1, 'd']],               1,   ['a', 0]) => [['a', 0], [0, 'd']]
replace([[1, 'd'], ['d', 1]],     1,   ['a', 0]) => [['a', 0], [0, 'd'], ['d', 'd'], ['d', 'a'], ['a', 0]]
replace([['d', 1], [1, 'd']],     1,   ['a', 0]) => [['d', 'a'], ['a', 0], [0, 'd']]
replace([[1, 1]],                 1,   ['a', 0]) => [['a', 0], [0, 'a'], ['a', 0]]
replace([[1, 1], [1, 1]],         1,   ['a', 0]) => [['a', 0], [0, 'a'], ['a', 0], [0, 'a'], ['a', 0]]
我猜我还是不明白格4,但你好像自己解决了,太好了!你知道吗

这是您修改后的代码:

def replace(t, a, b):
    # Flatten the list
    t1 = []
    l = len(t)-1
    for items in [t[i][0:(1 if i>-1 and i<l else 2)] for i in range(0,l+1)]:
        t1.extend(items)
    replaced = []
    # Iterate the elements of the flattened list
    # Let the elements that do not match a in and replace the ones that
    # do not match with the elements of b
    for elem in t1:
        if elem == a:  # this element matches, replace with b
            replaced.extend(b)
        else:          # this element does not, add it
            replaced.append(elem) 
    # break up the replaced, flattened list with groups of 2 elements
    return [replaced[x:x+2] for x in range(len(replaced)-1)]

相关问题 更多 >