私信  •  关注

Alain T.

Alain T. 最近创建的主题
Alain T. 最近回复了
2 年前
回复了 Alain T. 创建的主题 » 如何解决Python中大数问题的函数?

函数应该返回因子列表(而不是打印)。因为你要计算从1到1的所有潜在因子 a ,需要很长时间才能产生一个非常大的结果,比如600851475143。

为了加快运算速度,您可以成对提取因子,这样您只需查看整数平方根以下的除数。每次你找到数字(N)的一个因子(f),你就知道有一个对应的因子,它是N除以f(N/f)的结果。这意味着每个因素<=N有一个对应的>=N所以你可以让它们成对出现,只检查除数<=N

def factors(N):
    return [f for d in range(1,int(N**0.5)+1) if N%d==0 for f in {d,N//d}]

输出:

print(factor(600851475143))
[1, 600851475143, 8462696833, 71, 716151937, 839, 408464633, 1471, 
 6857, 87625999, 59569, 10086647, 104441, 5753023, 1234169, 486847]
2 年前
回复了 Alain T. 创建的主题 » Python循环从列表中删除重复项+原始项?

因为在到达输入文件的末尾之前,无法确定是否包含行,所以需要将所有未排除的行存储在内存中,然后才能将它们写入文件。

你可以用字典来做到这一点:

def csv_import(stream):

    ostream = StringIO()
    headers = stream.readline()
    ostream.write(headers)

    outputLines = dict()  # will use None for lines to exclude

    for row in stream:
        list_row = row.split(',')
        user_number = list_row[0]
        
        if user_number in outputLines:
            outputLines[user_number] = None
        else:
            outputLines[user_number] = row
        
    for row in filter(None,outputLines.values()):
        ostream.write(row)

    ostream.seek(0)
    return ostream
2 年前
回复了 Alain T. 创建的主题 » 如何在python中按n个元素分组元素,而无需列表切片?

有几种方法:

您可以使用嵌套列表理解,将索引放入列表中:

(不过,索引的广泛使用是非常不和谐的)

theList = list(range(10))
N       = 3
L       = len(theList)
subList = [ [theList[j] for j in range(i,min(i+N,L))] for i in range(0,L,N) ]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

你也可以用itertools来做。groupby使用迭代器作为分组键或itertools。每个子范围的islice(,N):

from itertools import groupby

group   = iter(range(len(theList)))
subList = [ list(g) for _,g in groupby(theList,key=lambda _:next(group)//N) ]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

from itertools import islice

iList   = iter(theList)
subList = [ list(islice(iList,N)) for _ in range(0,len(theList),N) ]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

如果不能使用库,可以使用zip()获取列表中的迭代器块:

iList   = iter(theList)
subList = [[n for _,n in zip(range(N),iList)] for _ in range(0,len(theList),N)]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

或者使用next()函数进行映射:

iList   = iter(theList)
subList = [ [f, *map(next,[iList]*(N-1))] for f in iList ]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] 

当然,总有好的for循环方法:

subList = [[]]
for n in theList:
    L,V = (subList[-1],n) if len(subList[-1])<N else (subList,[n]) 
    L.append(V)
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
2 年前
回复了 Alain T. 创建的主题 » 如何使用列表在python中添加新键和值?[闭门]

您可以使用zip将字典与内容字符串配对,并为每个字符串设置“内容”键:

dicList = [{'url': 'https://test.com/find/city-1', 'tit': 'title1', 'val': 1},
 {'url': 'https://test.com/find/city-2', 'tit': 'title1', 'val': 2},
 {'url': 'https://test.com/find/city-3', 'tit': 'title1', 'val': 3}
]
contents = ['a','b','c']
for d,c in zip(dicList,contents):
    d['content'] = c

print(dicList)

[{'url': 'https://test.com/find/city-1', 'tit': 'title1', 'val': 1, 'content': 'a'}, 
 {'url': 'https://test.com/find/city-2', 'tit': 'title1', 'val': 2, 'content': 'b'}, 
 {'url': 'https://test.com/find/city-3', 'tit': 'title1', 'val': 3, 'content': 'c'}]

或者,如果您希望结果出现在一个新的列表中,您可以使用列表理解来构建扩充字典:

dicList2 = [{**d, 'content':c} for d,c in zip(dicList,contents)]
2 年前
回复了 Alain T. 创建的主题 » 如何在python上显示斐波那契递归树

您可以定义一个类来保存二叉树节点,并根据递归斐波那契函数构建树:

class BNode:
    def __init__(self,value,left=None,right=None):
        self.value = value
        self.left  = left
        self.right = right
        
    def print(self):
        printBTree(self,nodeInfo=lambda n:(str(n.value),n.left,n.right))

from functools import lru_cache

@lru_cache()                   # optimize object count
def fiboTree(n):               # (n is an index, not a count)
    if n<2: return BNode(n)
    a,b = fiboTree(n-2),fiboTree(n-1)
    return BNode(a.value+b.value,a,b)

输出:

fiboTree(7).print()

                       13
          ____________/  \____________
         5                            8
   _____/ \____               _______/ \______
  2            3             3                5
 / \        __/ \_        __/ \_        _____/ \____
1   1      1      2      1      2      2            3
   / \    / \    / \    / \    / \    / \        __/ \_
  0   1  0   1  1   1  0   1  1   1  1   1      1      2
                   / \           / \    / \    / \    / \
                  0   1         0   1  0   1  0   1  1   1
                                                        / \
                                                       0   1

你可以找到 printBTree 作用 here

如果只需要说明调用层次结构,可以直接使用printBTree函数:

def fibo(n):
    n=int(n) # linking with strings to let zero come out as a node
    return (f"fibo({n})",[None,str(n-2)][n>1], [None,str(n-1)][n>1])


printBTree(5,fibo)

                      fibo(5)
            ____________/ \____________
     fibo(3)                           fibo(4)
       / \                          _____/ \____
fibo(1)   fibo(2)            fibo(2)            fibo(3)
            / \                / \                / \
     fibo(0)   fibo(1)  fibo(0)   fibo(1)  fibo(1)   fibo(2)
                                                       / \
                                                fibo(0)   fibo(1)

为了边打印边打印,我建议使用缩进来传达调用层次结构,否则重复添加的内容将很难与调用方联系起来。

def fibo(n,indent=""):
    if n<2: return n
    print(indent[:-3] + "|_ "*bool(indent) 
          + f"fibo({n}) = fibo({n-2}) + fibo({n-1})")
    return fibo(n-2,indent+"|  ")+fibo(n-1,indent+"   ") 



fibo(7)

fibo(7) = fibo(5) + fibo(6)
|_ fibo(5) = fibo(3) + fibo(4)
|  |_ fibo(3) = fibo(1) + fibo(2)
|  |  |_ fibo(2) = fibo(0) + fibo(1)
|  |_ fibo(4) = fibo(2) + fibo(3)
|     |_ fibo(2) = fibo(0) + fibo(1)
|     |_ fibo(3) = fibo(1) + fibo(2)
|        |_ fibo(2) = fibo(0) + fibo(1)
|_ fibo(6) = fibo(4) + fibo(5)
   |_ fibo(4) = fibo(2) + fibo(3)
   |  |_ fibo(2) = fibo(0) + fibo(1)
   |  |_ fibo(3) = fibo(1) + fibo(2)
   |     |_ fibo(2) = fibo(0) + fibo(1)
   |_ fibo(5) = fibo(3) + fibo(4)
      |_ fibo(3) = fibo(1) + fibo(2)
      |  |_ fibo(2) = fibo(0) + fibo(1)
      |_ fibo(4) = fibo(2) + fibo(3)
         |_ fibo(2) = fibo(0) + fibo(1)
         |_ fibo(3) = fibo(1) + fibo(2)
            |_ fibo(2) = fibo(0) + fibo(1)

这可以说明记忆的好处/效果:

def fibo(n,indent="",memo=None):
    if n<2: return n
    if memo is None: memo = dict()
    print(indent[:-3] + "|_ "*bool(indent) + f"fibo({n})",end=" = ")
    if n in memo:
        print("taken from memo")
    else:
        print(f"fibo({n-2}) + fibo({n-1})")
        memo[n] = fibo(n-2,indent+"|  ",memo)+fibo(n-1,indent+"   ",memo)
    return memo[n]

fibo(7) = fibo(5) + fibo(6)
|_ fibo(5) = fibo(3) + fibo(4)
|  |_ fibo(3) = fibo(1) + fibo(2)
|  |  |_ fibo(2) = fibo(0) + fibo(1)
|  |_ fibo(4) = fibo(2) + fibo(3)
|     |_ fibo(2) = taken from memo
|     |_ fibo(3) = taken from memo
|_ fibo(6) = fibo(4) + fibo(5)
   |_ fibo(4) = taken from memo
   |_ fibo(5) = taken from memo
5 年前
回复了 Alain T. 创建的主题 » 需要在多维数组列表python3中获取整个第一个元素(数组)

您还可以使用itertools的chain()函数展平列表中每个元素中第一个子数组的提取:

from itertools import chain
result = list(chain(*[sub[0] for sub in array]))
4 年前
回复了 Alain T. 创建的主题 » 如何在python中及时转换132这样的数字?

您可以使用divisions和module将数字分成100个块,然后在转换为带前导零的字符串后,使用“:”连接部分:

num = 132
result = ":".join( f"{num//10**i%100:02}" for i in (4,2,0) )

print(result) # '00:01:32'
  • 格式字符串,例如 f"{n:02}" 获取变量的值 n 并使其成为一个带前导零的2个位置的字符串。(即1-->'01')
  • ":".join(...) 获取字符串列表并将它们连接到一个字符串中,在列表中的每个项之间放置“:”
  • ( ... for i in (4,2,0) ) 是一个列表理解。它根据i的值生成一个3项列表,每个项的值分别为4、2和0。
  • num//10**i 是num除以10的整数除以i的幂。在列表理解(i将是4、2和0)中,这将产生num//10000、num//100和num//1。结果:0、1和132
  • %100 是模100。只取上面计算数的最后两位:0%100->0,1%100->1,132%100-->32

所有这些加起来产生格式化的时间

另一种方法(可能适用于较旧版本的python)是:

result = ":".join(str(10000+num)[-i:][:2] for i in (6,4,2))

如果不需要秒,可以在第一个示例中将元组更改为(2,0),在第二个示例中将元组更改为(4,2)。或者简单地使用: result = f"{num//100%100:02}:{num%100:02}"

4 年前
回复了 Alain T. 创建的主题 » 如何提高python代码的时间效率?

关键是使用一个集合来检查输入字符串中是否存在预期的数字。不过,您不需要将输入转换为整数。另一种方法是将序列号生成为字符串。

nums    = input().split()
numSet  = set(nums)
missing = " ".join(str(n) for n in range(1,len(nums)+1) if str(n) not in numSet)

print(missing) # 3 4

对于这个特定的问题,有一个比使用集合更快的选择,因为您可以创建一个具有已知(和合理)大小的标志数组:

numbers = input().split()
present = [False]*len(numbers)
for n in numbers: present[int(n)-1] = True
missing = " ".join(str(n+1) for n,seen in enumerate(present) if not seen)
4 年前
回复了 Alain T. 创建的主题 » 如何使for循环在python中更容易理解?

您的学生将从早期学习中受益,因为大多数编程语言使用基于零的索引。理解python的range()函数最简单的方法是只使用一个参数。

for i in range(10):
    # will iterate exactly 10 times with i going from 0 to 9

在一个零基础的世界里,这是完全有意义的。

python的范围(以区间表示法)有一个独占的上限:[0..[10,而非计算机工程师默认使用的包含区间[1…10]

鉴于此,给range函数的参数被理解为唯一的“stop”值。

当您使用一个额外的参数来提供一个起点时,突然以不同的方式处理停止值是不一致的。这将使range(0,10)的行为与range(10)不同,这将非常令人困惑。

与c的主要区别在于range()表示“小于”比较,而不是“小于或等于”:

 for i in range(A,B):   # for (i=A;i<B;i++)
     ...

你可以给你的学生提供一个“inclusiverange”函数,让他们在不掌握零基础概念的情况下开始学习。

 def inclusiveRange(start=0,end,step=1):
     return range(start,end+1,step)

他们可以用它代替range()

 for i in inclusiveRange(1,10):
     ... # will iterate from 1 to 10 inclusively

缺点是,当学生开始使用列表索引或计算坐标系中的位置时,必须“取消学习”循环。你可以救他们很多 - 1 off by one 在未来,通过现在的零基索引让他们上船。

5 年前
回复了 Alain T. 创建的主题 » 从python中的地址中删除电子邮件域[重复]

您可以简单地使用:

prompt.split("@")[0]