jjzjj

Python - 将列表元素与 'neighbour' 元素进行比较

coder 2023-08-24 原文

这可能更像是一个“方法”或概念性问题。

基本上,我有一个像这样的 python 多维列表:

my_list = [[0,1,1,1,0,1], [1,1,1,0,0,1], [1,1,0,0,0,1], [1,1,1,1,1,1]]

我必须做的是遍历数组并将每个元素与直接围绕它的元素进行比较,就好像列表被布置为矩阵一样。

例如,给定第一行的第一个元素,my_list[0][0] ,我需要知道 my_list[0][1] 的值, my_list[1][0]my_list[1][1] . “周围”元素的值将决定应如何操作当前元素。当然,对于数组中心的元素,需要进行 8 次比较。

现在我知道我可以简单地遍历数组并与索引值进行比较,如上所述。我很好奇是否有更有效的方法来限制所需的迭代量?我应该按原样遍历数组,还是只迭代和比较任一侧的值,然后转置数组并再次运行它。但是,这会忽略对角线的那些值。我是否应该存储元素查找的结果,这样我就不会多次确定同一元素的值?

我怀疑这可能是计算机科学中的一个基本方法,我很想获得有关使用 Python 的最佳方法的反馈,而不是寻找我的问题的具体答案。

最佳答案

通过使用 numpy 或其他替代方法(详情请参见下文),您的代码可能会变得更快,甚至可能更简单。但从理论的角度来看,就算法复杂度而言,你能得到的最好的是 O(N*M),你可以用你的设计来做到这一点(如果我理解正确的话)。例如:

def neighbors(matrix, row, col):
    for i in row-1, row, row+1:
        if i < 0 or i == len(matrix): continue
        for j in col-1, col, col+1:
            if j < 0 or j == len(matrix[i]): continue
            if i == row and j == col: continue
            yield matrix[i][j]

matrix = [[0,1,1,1,0,1], [1,1,1,0,0,1], [1,1,0,0,0,1], [1,1,1,1,1,1]]

for i, row in enumerate(matrix):
    for j, cell in enumerate(cell):
        for neighbor in neighbors(matrix, i, j):
            do_stuff(cell, neighbor)

这需要 N * M * 8 个步骤(实际上,比那个少一点,因为许多单元格的邻居少于 8 个)。从算法上讲,没有比 O(N * M) 更好的方法了。至此,大功告成。


(在某些情况下,通过考虑迭代器转换,您可以使事情变得更简单 — 两种方式都不会显着改变性能。例如,您可以轻松地从列表 a 的相邻三元组上创建一个石斑鱼 通过正确压缩 aa[1:]a[2:],您可以将其扩展到相邻的二维 nonets。但我认为在这种情况下,编写显式 neighbors 迭代器和显式 for 循环矩阵只会使您的代码更复杂。)


但是,实际上,您可以通过多种方式获得更快的速度。例如:

  • 使用numpy ,你可能会得到一个数量级左右的速度。当您迭代一个紧密的循环并进行简单的算术运算时,这是 Python 特别慢的事情之一,而 numpy 可以用 C(或 Fortran)代替。
  • 使用您最喜欢的 GPGPU 库,您可以明确地矢量化您的操作。
  • 使用multiprocessing ,您可以将矩阵分解成多个部分,并在不同的核心(甚至不同的机器)上并行执行多个部分。

当然,对于单个 4x6 矩阵,这些都不值得做......可能除了 numpy,它可以使你的代码更简单和更快,只要你能自然地表达你的操作在矩阵/广播方面。

事实上,即使你不能很容易地用这种方式表达东西,仅仅使用 numpy存储矩阵可能会让事情变得更简单(并节省一些内存,如果这很重要)。例如,numpy 可以让您自然地访问矩阵中的单个列,而在纯 Python 中,您需要编写类似 [row[col] for row in matrix].


那么,您将如何使用 numpy 解决这个问题?

首先,您应该阅读 numpy.matrixufunc (或者,更好的是,一些更高级别的教程,但我没有可以推荐的教程),然后再深入。

无论如何,这取决于您对每组邻居的处理方式,但有以下三个基本想法。

首先,如果您可以将您的操作转换为简单的矩阵数学,那总是最简单的。

如果没有,您可以通过在每个方向上移动矩阵来创建 8 个“邻域矩阵”,然后对每个邻域执行简单的操作。对于某些情况,从外缘具有合适“空”值(通常为 0 或 nan)的 N+2 x N+2 矩阵开始可能更容易。或者,您可以移动矩阵并填充空值。或者,对于某些操作,您不需要大小相同的矩阵,因此您可以裁剪矩阵以创建一个邻居。这实际上取决于您要执行的操作。

例如,将您的输入作为 Game of Life 的固定 6x4 板:

def neighbors(matrix):
    for i in -1, 0, 1:
        for j in -1, 0, 1:
            if i == 0 and j == 0: continue
            yield np.roll(np.roll(matrix, i, 0), j, 1)

matrix = np.matrix([[0,0,0,0,0,0,0,0],
                    [0,0,1,1,1,0,1,0],
                    [0,1,1,1,0,0,1,0],
                    [0,1,1,0,0,0,1,0],
                    [0,1,1,1,1,1,1,0],
                    [0,0,0,0,0,0,0,0]])
while True:
    livecount = sum(neighbors(matrix))
    matrix = (matrix & (livecount==2)) | (livecount==3)

(请注意,这不是解决此问题的最佳方法,但我认为它相对容易理解,并且可能会阐明您的实际问题。)

关于Python - 将列表元素与 'neighbour' 元素进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16529838/

有关Python - 将列表元素与 'neighbour' 元素进行比较的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  4. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  7. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  8. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  9. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  10. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

随机推荐