如何在list/dict/etc中“任意”格式化项目例如:更改lis中每个字符串的第四个字符

2024-09-30 16:28:42 发布

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

首先,我想说的是,对于我创建的这个简单的脚本,可能没有任何实际的应用程序,但是我这么做是因为我在学习,我在这里找不到任何类似的东西。我想知道怎样才能“任意”改变像列表这样的iterable中的字符。在

{我最后想学的是一个比较快的大写字母,但我想用的是什么格式?或者第三个,中间的,等等。小写呢?用其他字符替换特定字符?在

就像我说的,这当然不是完美的,但可以给像我这样的傻瓜一些思考的东西。另外,我认为这可以通过数百种方式修改来实现各种不同的格式。在

帮我改进一下我刚做的事怎么样?不如把它变得更简洁和刻薄些?检查风格、方法、效率等。。。在

接下来是:

words = ['house', 'flower', 'tree']  #string list

counter = 0                          #counter to iterate over the items in list
chars = 4                            #character position in string (0,1,2...)

for counter in range (0,len(words)): 
    while counter < len(words):
        z = list(words[counter])     # z is a temp list created to slice words
        if len(z) > chars:           # to compare char position and z length
            upper = [k.upper() for k in z[chars]] # string formatting EX: uppercase
            z[chars] = upper [0]     # replace formatted character with original
            words[counter] = ("".join(z)) # convert and replace temp list back into original word str list
            counter +=1
        else:
            break

print (words)

['housE', 'flowEr', 'tree']

Tags: tointreeforstringlen格式counter
3条回答

有比我强得多的Python,但这里有一个尝试:

[''.join(
      [a[x].upper() if x == chars else a[x]
          for x in xrange(0,len(a))]
    )
    for a in words]

另外,我们说的是程序员的第四个,对吧?其他人都叫第五,是吗?在

对代码的一些注释:

for counter in range (0,len(words)):     
while counter < len(words):

除非在for循环下缩进while循环,否则无法编译。而且,如果你这样做,内环会把外环的循环计数器完全搞砸。最后,您几乎永远不想在Python中维护显式循环计数器。你可能想要这个:

^{pr2}$

下一步:

z = list(words[counter])     # z is a temp list created to slice words

您已经可以用与切片列表完全相同的方式对字符串进行切片,因此这是不必要的。在

下一步:

    upper = [k.upper() for k in z[chars]] # string formatting EX: uppercase

这是一个错误的变量名,因为在同一行中有一个与您调用的函数同名。在

同时,你定义事物的方式,z[chars]是一个字符,words[4]的副本。您可以在Python中迭代单个字符,因为每个字符本身就是一个字符串。但这通常是没有意义的-[k.upper() for k in z[chars]]和{}是一回事。在

    z[chars] = upper [0]     # replace formatted character with original

所以你只想让1个字符的列表从中取出第一个字符…为什么要把它列为一个列表呢?只需将最后两行替换为z[chars] = z[chars].upper()。在

else:
    break

这将在第一个长度小于4的字符串处停止,而不是跳过长度小于4的字符串,这正是您想要的。这样说是continue,而不是{}。或者,最好是从名单的末尾掉下来。在某些情况下,没有continue很难写东西,但在这种情况下,很容易它已经在循环的末尾,而且实际上它在一个else:中,它没有其他内容,所以只需删除这两行。在

很难用upper来判断你的循环是错误的,因为如果你不小心调用了upper两次,看起来就像你调用了一次一样。将upper更改为chr(ord(k)+1),这将用下一个字母替换任何字母。然后试试:

words = ['house', 'flower', 'tree', 'a', 'abcdefgh']

您会注意到,例如,您得到的是'flowgr',而不是{}。在

您可能还需要添加一个变量,该变量用于计算运行内部循环的次数。它应该是len(words)次,但如果你没有短单词,它实际上是len(words) * len(words),如果你有短单词,len(words) * len(<up to the first short word>)。如果你有1000个单词,你会让电脑做很多额外的工作,它必须做1000000个循环,而不是1000个。从技术上讲,你的算法是O(N^2),即使它只需要是O(N)。在

综合起来:

words = ['house', 'flower', 'tree', 'a', 'abcdefgh']  #string list
chars = 4                            #character position in string (0,1,2...)

for counter, word in enumerate(words): 
    if len(word) > chars:           # to compare char position and z length
        z = list(word)
        z[chars] = chr(ord(z[chars]+1) # replace character with next character
        words[counter] = "".join(z)    # convert and replace temp list back into original word str list

print (words)

这和你的原始代码一样(除了使用“next character”而不是“uppercase character”),没有bug,对计算机的工作更少,更容易阅读。在

这在某种程度上是两者的结合(所以两者都是+1)。main函数接受列表、任意函数和要操作的字符:

In [47]: def RandomAlter(l, func, char):
    return [''.join([func(w[x]) if x == char else w[x] for x in xrange(len(w))]) for w in l]
   ....:

In [48]: RandomAlter(words, str.upper, 4)
Out[48]: ['housE', 'flowEr', 'tree']

In [49]: RandomAlter([str.upper(w) for w in words], str.lower, 2)
Out[49]: ['HOuSE', 'FLoWER', 'TReE']

In [50]: RandomAlter(words, lambda x: '_', 4)
Out[50]: ['hous_', 'flow_r', 'tree']

函数RandomAlter可以重写为这样,这可能会使它更清楚一些(它利用一个名为list comprehensions的特性来减少所需的代码行)。在

^{pr2}$

相关问题 更多 >