简体   繁体   English

在 Python 函数中使用递归输出元组列表

[英]Using recursion in Python function to output a list of tuples

I'm very new to python and would kindly appreciate any help.Basically im inputting a string and returning the string "encoded" if you like.我对 python 很陌生,如果你愿意,我会很感激任何帮助。基本上我输入一个字符串并返回“编码”的字符串。 I'm having problems however with my function, i don't know where i'm going wrong.但是我的功能有问题,我不知道我哪里出错了。

def encode_it(x):
    output = []
    counter = 1
    while x[0] != x[-1]:
        if x[0] == x[1]:
            counter += 1
            return encode_it(x[1:])
        else:
            output += (x[0],counter)
            counter = 1
            return encode_it(x[1:])

    return output

the result i want is this:我想要的结果是这样的:

>>>encode_it("qqqqppttyl")
[("q",4),("p",2),("t",2),("y",1),("l",1)]

I would really appreciate any help, I'm just learning python and trying my hand at recursion, if there was even an easier way of doing this without recursion i'd be really grateful :)我真的很感激任何帮助,我只是在学习 python 并尝试递归,如果有更简单的方法来做到这一点而没有递归,我将非常感激:)

Thanks guys!!谢谢你们!! in response to L3viathan's code , i modified it so it would output the result but it doesnt add the last character to the list:为了响应 L3viathan 的代码,我对其进行了修改,因此它会输出结果,但不会将最后一个字符添加到列表中:

def encode_it(x):
last_char = None
num = 0
result = []
for char in x:
    t = ( )
    if last_char == char:
        num += 1
    else:
        if last_char:
            t += last_char,num
            result += t
        last_char = char
        num = 1
return result 

if i was to call encode_it("qqqeerrw"), the result i would get is:如果我要调用 encode_it("qqqeerrw"),我会得到的结果是:

['q', 3, 'e', 2, 'r', 2] #it's leaving out the w here?

also, the reason i have an empty tuple 't' and an empty list 'result' is because, i want each character to be in its own tuple with its count...like so:另外,我有一个空元组 't' 和一个空列表 'result' 的原因是,我希望每个字符都在它自己的元组中,并带有它的计数......像这样:

[("q",3),("e",2),("r",2),("w",1)]

This task is easily done by itertools.groupby :这个任务很容易通过itertools.groupby完成:

def encode_it(txt):
    return ((c, len(tuple(grp))) for c, grp in itertools.groupby(txt))

Then:然后:

>>> list(encode_it("qqqqppttyl"))
[('q', 4), ('p', 2), ('t', 2), ('y', 1)]

One of the issues of your code is that output is reinitialized as an empty list on every recursive call.您的代码的问题之一是每次递归调用时output被重新初始化为空列表。 In the final case, when you're through the complete string, the newly created empty list is returned (and then also handed back through all of the recursive calls).在最后一种情况下,当您完成整个字符串时,将返回新创建的空列表(然后还通过所有递归调用返回)。


This is a solution without recursion, as a generator:这是一个没有递归的解决方案,作为一个生成器:

def encode_it(x):
    last_char = None
    num = 0
    for char in x:
        if last_char == char:
            num += 1
        else:
            if last_char:
                yield (last_char, num)
            last_char = char
            num = 1

Usage:用法:

>>> list(encode_it("qqqqppttyl"))
[('q', 4), ('p', 2), ('t', 2), ('y', 1)]

The way this works is by iterating over the string, and testing whether the current character is the same as the one saved in last_char .其工作方式是遍历字符串,并测试当前字符是否与last_char保存的字符相同。 If so, we just increment a counter.如果是这样,我们只需增加一个计数器。 If it isn't, we yield the tuple of the last character along with its count, and set new values for last_char and num .如果不是,我们yield最后一个字符的元组及其计数,并为last_charnum设置新值。

A generator doesn't return a list, but instead a generator object, so to turn it into a list, you can call list() on it.生成器不返回列表,而是返回生成器对象,因此要将其转换为列表,您可以对其调用list()

A simple recursive (as it was asked) solution to the problem:一个简单的递归(按照要求)解决问题:

def encode_it(x):
    if not x:  # base case: empty string
        return []
    i, c = 1, x[0] 
    while i < len(x) and c == x[i]:
        i += 1
    return [(c, i)] + encode_it(x[i:])

You can easily without recursion using the count method and a single line for loop.您可以轻松地使用count方法和单行for循环而无需递归。

def encode_it(x):
   return [(char,x.count(char)) for char in x]

list.count(x) return the number of times x appears in the list. list.count(x)返回 x 在列表中出现的次数。

A messy one-liner:凌乱的单线:

def encode_it(x):
    return [(c,x.count(c,i,next((i for i, v in enumerate(x) if v != c), -1))) for i, c in enumerate(x) if x.index(c) == i]

Below solution will also work if same character are not in sequence also, without using recursion function.如果相同的字符也没有按顺序排列,则下面的解决方案也将起作用,而不使用递归函数。

For Example given string is something例如给定的字符串是一些东西

>>>groupBy("qqqqqq1212")
[('q', 6), ('1', 2), ('2', 2)]

or或者

>>>groupBy("qqqqqq1212tytl")
[('y', 1), ('q', 6), ('1', 2), ('l', 1), ('t', 2), ('2', 2)]

Program without recursion function没有递归函数的程序

str = "qqqqqq1212tytl"

def groupBy(str):
   result = []
   count = {}
   for c in str:
      if c in count:
          count[c] += 1
      else:
          count[c] = 1

   for key in count:
      if count[key] >= 1:
          result +=  [(key, count[key])]            

   return result           


print(groupBy(str))

Please let me know, how can it be better coded by use of recursive function?请让我知道,如何使用递归函数更好地编码?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM